DLL注入无效果求助:32位程序注入后无反应问题排查
DLL注入无响应问题排查求助
注入器C代码
#include <Windows.h> #include <TlHelp32.h> #include <stdio.h> DWORD get_pid(char * targetProcess) { HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snap && snap != INVALID_HANDLE_VALUE) { PROCESSENTRY32 pe; pe.dwSize = sizeof(pe); if (Process32First(snap, &pe)) { do { if (!_stricmp(pe.szExeFile, targetProcess)) { CloseHandle(snap); return pe.th32ProcessID; } } while (Process32Next(snap, &pe)); } } return 0; } int main() { char * dllpath = "dllmain.dll"; char * processToInject = "Robots.exe"; long pid = 0; while (!pid) { pid = get_pid(processToInject); Sleep(10); } HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); if (hProc && hProc != INVALID_HANDLE_VALUE) { void * loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); WriteProcessMemory(hProc, loc, dllpath, strlen(dllpath) + 1, 0); HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0); CloseHandle(hThread); } CloseHandle(hProc); return 0; }
DLL代码(DllMain弹窗测试)
#include <Windows.h> BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpvReserved){ if (fdwReason == DLL_PROCESS_ATTACH){ MessageBoxA(NULL, "INECTION WORKED!", "INJECTION WORKED!", MB_OK); } while(true){ Sleep(10); } return true; }
问题描述与已尝试操作
目标程序是2005年的32位游戏,注入器运行无报错,但注入后无任何反应。已完成以下排查:
- 以32位编译DLL和注入器程序
- 尝试注入32位和64位其他程序,均无效
- 确认DLL路径正确,文件存在
- 验证目标进程ID(PID)正确
- 确认WriteProcessMemory返回成功
关键问题分析与解决建议
1. DllMain死循环是核心阻塞点
DllMain是系统加载DLL时的入口函数,系统会等待DllMain返回后才完成DLL加载流程。你的代码在PROCESS_ATTACH分支后直接进入无限Sleep循环,会导致:
- 目标进程加载DLL的线程被永久阻塞,无法完成初始化
- 弹窗代码虽在前面,但系统还未处理消息就被卡死
- 极端情况会导致目标进程无响应
修复方案:移除DllMain中的死循环,若需持续运行逻辑,应在PROCESS_ATTACH时创建独立线程执行:
#include <Windows.h> DWORD WINAPI WorkerThread(LPVOID lpParam) { while(true){ Sleep(10); } return 0; } BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpvReserved){ if (fdwReason == DLL_PROCESS_ATTACH){ MessageBoxA(NULL, "INJECTION WORKED!", "INJECTION WORKED!", MB_OK); // 创建新线程执行循环逻辑 CreateThread(NULL, 0, WorkerThread, NULL, 0, NULL); } return true; }
2. 权限请求过大导致OpenProcess失败
PROCESS_ALL_ACCESS需要极高权限,多数场景下系统会拒绝该请求。应使用最小必要权限集:
// 替换原OpenProcess调用 HANDLE hProc = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid );
3. 相对路径导致目标进程找不到DLL
注入器中的"dllmain.dll"是相对路径,该路径基于目标进程的工作目录而非注入器运行目录。若游戏安装在独立目录,DLL不在该目录下则LoadLibraryA会加载失败。
修复方案:使用DLL绝对路径,例如:
char * dllpath = "C:\\YourInjectorDir\\dllmain.dll";
4. 增加API错误检查定位失败点
代码缺少关键API的错误校验,比如VirtualAllocEx、CreateRemoteThread是否成功,无法定位具体故障环节。建议添加错误检查:
void * loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!loc) { printf("VirtualAllocEx failed: %d\n", GetLastError()); CloseHandle(hProc); return 1; } BOOL writeSuccess = WriteProcessMemory(hProc, loc, dllpath, strlen(dllpath) + 1, NULL); if (!writeSuccess) { printf("WriteProcessMemory failed: %d\n", GetLastError()); VirtualFreeEx(hProc, loc, 0, MEM_RELEASE); CloseHandle(hProc); return 1; } HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0); if (!hThread) { printf("CreateRemoteThread failed: %d\n", GetLastError()); VirtualFreeEx(hProc, loc, 0, MEM_RELEASE); CloseHandle(hProc); return 1; } // 等待线程执行完成,确认DLL加载状态 WaitForSingleObject(hThread, INFINITE); DWORD exitCode; GetExitCodeThread(hThread, &exitCode); if (exitCode == NULL) { printf("LoadLibraryA failed (returned NULL)\n"); } CloseHandle(hThread);
5. 权限一致性问题
若目标进程以管理员权限运行,注入器也需以管理员身份启动,否则会因权限不足无法完成注入。右键点击注入器选择"以管理员身份运行"重试。
内容的提问来源于stack exchange,提问作者Andreas Sandberg
相关产品推荐
相关产品推荐

