C语言Windows进程注入遇类型错误及Shellcode注入无效果求助
进程注入问题的解决方案
一、字符串类型不匹配错误修复
错误原因
PROCESSENTRY32 结构的 szExeFile 成员类型由编译环境是否定义 UNICODE 宏决定:
- 未定义
UNICODE时,szExeFile为CHAR*(窄字符),但代码中使用了宽字符比较函数wcscmp和宽字符串字面量L"mspaint.exe",导致类型不匹配编译错误。 - 定义
UNICODE时,szExeFile为WCHAR*(宽字符),此时wcscmp与宽字符串匹配,可正常使用。
解决方法
方案1:使用ANSI字符串比较
将宽字符比较函数替换为ANSI版本,同时去掉字符串前的 L 前缀:
if (strcmp(pe32.szExeFile, "mspaint.exe") == 0)
方案2:启用UNICODE编译
在代码最开头添加宏定义,强制使用Windows API的宽字符版本:
#define UNICODE #define _UNICODE
此方案下原代码的 wcscmp 和 L"mspaint.exe" 可正常工作。
二、Shellcode注入后消息框不显示问题排查
1. 修复VirtualFreeEx参数错误
当前代码中 VirtualFreeEx 的第一个参数误用了线程句柄 hThread,正确参数应为目标进程句柄 hProcess:
VirtualFreeEx(hProcess, allocated_mem, 0, MEM_RELEASE);
2. 调整OpenProcess权限并增加检查
PROCESS_ALL_ACCESS 权限过高,容易因系统权限限制导致调用失败,建议使用最小必要权限集合:
HANDLE hProcess = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, pe32.th32ProcessID );
同时必须检查进程句柄是否创建成功,当前代码遗漏了此检查:
if (hProcess == NULL) { printf("OpenProcess failed: %u\n", GetLastError()); return 1; }
3. 验证WriteProcessMemory执行结果
未检查内存写入是否成功,若写入失败后续操作无意义,需添加验证逻辑:
BOOL writeResult = WriteProcessMemory( hProcess, allocated_mem, shellcode, sizeof(shellcode), NULL ); if (!writeResult) { printf("WriteProcessMemory failed: %u\n", GetLastError()); VirtualFreeEx(hProcess, allocated_mem, 0, MEM_RELEASE); CloseHandle(hProcess); return 1; }
4. 确保Shellcode与目标进程架构匹配
Shellcode的指令集必须与目标进程的位数(32位/64位)完全一致:
- 若注入32位
mspaint.exe,需使用32位Shellcode;若注入64位进程,需使用64位Shellcode。 - 示例32位MessageBox Shellcode(调用
MessageBoxA,位置无关):
unsigned char shellcode[] = { 0x31, 0xFF, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x68, 0x6D, 0x73, 0x67, 0x31, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x68, 0x57, 0x6F, 0x72, 0x6C, 0x54, 0xBA, 0x00, 0x00, 0x00, 0x00, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, 0x31, 0xC0, 0x5F, 0x5E, 0x5D, 0x5B, 0x5A, 0x59, 0xC3 };
5. 修正错误提示信息
当前代码中CreateRemoteThread失败时的提示文本与实际错误不符,需修正:
if (hThread == NULL) { printf("CreateRemoteThread failed: %u\n", GetLastError()); VirtualFreeEx(hProcess, allocated_mem, 0, MEM_RELEASE); CloseHandle(hProcess); return 1; }
完整修正代码示例
#define UNICODE #define _UNICODE #include <windows.h> #include <tlhelp32.h> #include <stdio.h> unsigned char shellcode[] = { // 替换为与目标进程匹配的Shellcode 0x31, 0xFF, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x68, 0x6D, 0x73, 0x67, 0x31, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x68, 0x57, 0x6F, 0x72, 0x6C, 0x54, 0xBA, 0x00, 0x00, 0x00, 0x00, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, 0x31, 0xC0, 0x5F, 0x5E, 0x5D, 0x5B, 0x5A, 0x59, 0xC3 }; int main() { PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) { printf("CreateToolhelp32Snapshot failed: %u\n", GetLastError()); return 1; } if (!Process32First(snapshot, &pe32)) { printf("Process32First failed: %u\n", GetLastError()); CloseHandle(snapshot); return 1; } do { if (wcscmp(pe32.szExeFile, L"mspaint.exe") == 0) { HANDLE hProcess = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, pe32.th32ProcessID ); if (hProcess == NULL) { printf("OpenProcess failed: %u\n", GetLastError()); CloseHandle(snapshot); return 1; } LPVOID allocated_mem = VirtualAllocEx( hProcess, NULL, sizeof(shellcode), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if (allocated_mem == NULL) { printf("VirtualAllocEx failed: %u\n", GetLastError()); CloseHandle(hProcess); CloseHandle(snapshot); return 1; } printf("Memory allocated at: 0x%p\n", allocated_mem); BOOL writeResult = WriteProcessMemory( hProcess, allocated_mem, shellcode, sizeof(shellcode), NULL ); if (!writeResult) { printf("WriteProcessMemory failed: %u\n", GetLastError()); VirtualFreeEx(hProcess, allocated_mem, 0, MEM_RELEASE); CloseHandle(hProcess); CloseHandle(snapshot); return 1; } HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)allocated_mem, NULL, 0, NULL ); if (hThread == NULL) { printf("CreateRemoteThread failed: %u\n", GetLastError()); VirtualFreeEx(hProcess, allocated_mem, 0, MEM_RELEASE); CloseHandle(hProcess); CloseHandle(snapshot); return 1; } WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(hProcess, allocated_mem, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); break; } } while (Process32Next(snapshot, &pe32)); CloseHandle(snapshot); return 0; }
内容的提问来源于stack exchange,提问作者Iván Soler
相关产品推荐
相关产品推荐

