使用CreateRemoteThread+LoadLibrary向64位Windows进程注入DLL时返回退出码0失败的原因排查
CreateRemoteThread+LoadLibrary向64位Windows进程注入DLL时返回退出码0失败的原因排查
看起来你的问题核心出在字符编码不匹配上,这是64位DLL注入中非常容易踩的坑,咱们一步步拆解问题和修复方案:
1. 最直接的原因:LoadLibraryW 与 ANSI 路径不兼容
你的代码里犯了一个关键的类型不匹配错误:
- 你传入的DLL路径是
const char*类型的ANSI窄字符串,用strlen计算长度,通过WriteProcessMemory写入的也是窄字符字节。 - 但你通过
GetProcAddress获取的是LoadLibraryW的地址——这是LoadLibrary的宽字符版本,它期望接收的是LPCWSTR(宽字符指针)参数。
当远程线程执行LoadLibraryW时,会把你写入的ANSI字节序列当作宽字符解析,这会导致路径完全乱码(比如原本的F:\...会被解析成完全无意义的宽字符组合),自然找不到目标DLL,最终返回0。
2. 快速修复方案
你有两种选择来解决这个编码不匹配问题:
方案一:改用 LoadLibraryA(适配ANSI路径)
既然你用的是ANSI格式的路径,直接获取LoadLibraryA的地址即可,和你的参数类型完全匹配:
// 替换原来的pLoadLibrary赋值代码 LPVOID pLoadLibrary = reinterpret_cast<LPVOID>( GetProcAddress( GetModuleHandleA("kernel32.dll"), // 用A版本的GetModuleHandle "LoadLibraryA" // 取LoadLibraryA的地址 ) );
方案二:切换为宽字符路径(适配LoadLibraryW)
如果想使用宽字符版本,需要把整个路径处理逻辑改成宽字符:
// 1. 把DLL路径改成宽字符 const wchar_t* DLLpath = L"F:\\project\\LearnMaliciouCode\\RemoteThreadInjector\\x64\\Debug\\DLL\\Dll3.dll"; // 2. 注入函数中调整内存分配、写入的逻辑: pRemoteMem = VirtualAllocEx( hProcess, NULL, (wcslen(DLLpath)+1) * sizeof(wchar_t), // 宽字符每个占2字节 MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); if (!WriteProcessMemory( hProcess, pRemoteMem, DLLpath, (wcslen(DLLpath)+1) * sizeof(wchar_t), nullptr )) { std::cerr << "[!] WriteProcessMemory failed: " << GetLastError() << std::endl; return FALSE; } // 3. 继续使用LoadLibraryW LPVOID pLoadLibrary = reinterpret_cast<LPVOID>( GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW") );
3. 其他需要注意的细节
除了编码问题,还有几个点可以优化或检查:
- 最小权限原则:你现在用的
PROCESS_ALL_ACCESS权限过大,系统可能在某些场景下拒绝该权限请求。建议使用最小必要权限:PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,这样更稳妥。 - 错误处理的误区:你在
GetExitCodeThread后调用GetLastError()是无效的!GetLastError()是线程局部存储的,当前进程的错误码和远程线程的错误码完全无关。如果想知道远程进程中LoadLibrary失败的具体原因,需要在DLL的DLL_PROCESS_ATTACH中记录错误(比如写入日志文件),而不是在注入器中获取当前进程的GetLastError()。 - 路径的绝对/相对问题:确保你传入的是绝对路径,远程进程的工作目录可能和注入器不同,相对路径容易导致找不到DLL(不过你已经用了绝对路径,这点没问题)。
4. 验证修复效果
修改后重新编译注入器和DLL,再次执行注入,应该就能看到LoadLibrary返回非0值,DLL成功加载。
内容来源于stack exchange




