CreateRemoteThread() 成功但不做任何事情
CreateRemoteThread() succeeds yet doesn't do anything
我试图使用CreateRemoteThread()
注入dll(在dll_path[]
中发现,它的正确的路径)到目标进程。不幸的是,完全没有发生(预期的结果是MessageBox()
从DLL_PROCESS_ATTACH
调用导致窗口弹出)。当与远程注入器一起使用时,工作正常。
您可以将每个what()
调用视为GetLastError()
和assert(0)
。可以保证变量PID
将包含正确的进程id(我测试了很多次)。下面代码中看到的函数调用none也会失败。有趣的是,在我将它从C重写为更像c++的代码之前,它一直运行良好,如下所示。我编译了下面的代码和dll代码,没有任何警告。我不知道我哪里出错了。下面是我的代码:
int main() {
const WCHAR dll_path[] = L"C:\myDLL.dll";
const std::wstring process_name = L"target.exe";
const DWORD PID = get_PID(process_name);
if (!PID)
what();
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
if (!process)
what();
FARPROC lib = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
if (!lib)
what();
LPVOID base = (LPVOID)VirtualAllocEx(process, 0, wcslen(dll_path), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!base)
what();
BOOL good = WriteProcessMemory(process, base, dll_path, wcslen(dll_path), 0);
if (!good)
what();
HANDLE thread = CreateRemoteThread(process, 0, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(lib), base, 0, 0);
if (!thread)
what();
if (thread) {
std::cout << "Remote thread successfully created." << std::endl;
std::cout << "process ID = " << PID << std::endl;
}
#if 1
CloseHandle(thread);
CloseHandle(process);
#endif
return 0;
}
正如@adelphus所说,当你应该使用LoadLibraryW()
时,你正在使用LoadLibraryA()
。
更重要的是,您没有在远程进程中分配足够的内存来容纳宽 DLL路径字符串。VirtualAllocEx()
和WriteProcessMemory()
操作的是字节,而不是字符。并且您需要确保分配和也复制字符串的空终止符。所以你需要使用(wcslen(dll_path) + 1) * sizeof(WCHAR)
,或者你可以使用sizeof(dll_path)
,因为它是一个静态数组。
现在,既然远程线程过程是LoadLibrary()
本身,那么线程的退出代码将是LoadLibrary()
的返回值。如果CreateRemoteThread()
成功,可以调用WaitForSingleObject()
等待线程终止,然后调用GetExitCodeThread()
获取LoadLibrary()
的返回值。如果为0,则LoadLibrary()
失败,即使线程本身成功。
int main() {
const WCHAR dll_path[] = L"C:\myDLL.dll";
const int dll_path_size = (wcslen(dll_path) + 1) * sizeof(WCHAR); // or sizeof(dll_path);
const std::wstring process_name = L"target.exe";
const DWORD PID = get_PID(process_name);
if (!PID)
what();
HANDLE process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, PID);
if (!process)
what();
FARPROC lib = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
if (!lib)
what();
LPVOID base = VirtualAllocEx(process, 0, dll_path_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!base)
what();
BOOL good = WriteProcessMemory(process, base, dll_path, dll_path_size, 0);
if (!good)
what();
HANDLE thread = CreateRemoteThread(process, 0, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(lib), base, 0, 0);
if (!thread)
what();
std::cout << "Remote thread successfully created." << std::endl;
std::cout << "process ID = " << PID << std::endl;
WaitForSingleObject(thread, INFINITE);
DWORD exitCode = 0;
GetExitCodeThread(thread, &exitCode);
if (exitCode != 0)
std::cout << "DLL loaded successfully." << std::endl;
else
std::cout << "DLL load failed." << std::endl;
#if 1
CloseHandle(thread);
CloseHandle(process);
#endif
return 0;
}
不幸的是,您将无法发现LoadLibrary()
失败的原因,除非您更改远程线程逻辑以注入整个函数,该函数同时调用LoadLibrary()
和GetLastError()
,然后返回GetLastError()
的值。GetLastError()
的值存储在线程本地存储中。一个线程不能读取另一个线程的错误代码(除非您深入到操作系统的碗中并直接读取远程线程的TIB结构)。
最后,一定要考虑目标进程是32位还是64位。不能将32位DLL注入64位进程,反之亦然。
您正在调用LoadLibraryA
的指针,指向一个宽字符字符串。你可能是指LoadLibraryW
?
- cmake在我的项目中所需的所有静态库都不成功
- 尽管测试成功,CppUnit测试核心仍被丢弃.为什么
- 如何让LLDB在成功时退出,在失败时等待
- 有没有办法知道Tracer是否成功地完全连接到了jaegerclientcpp中的jaeger后端服务器
- CMake WxWidgets项目成功地在Linux上构建,但没有在Windows上构建
- 为什么 std::绑定错误参数可以成功?
- Clion显示错误,但可以使用Cmake成功构建代码
- 代码使用向量成功运行,但使用数组显示错误
- 如何检查cURL是否成功登录?c ++
- 为什么 WinInet 在通过 FQDN 连接时无法通过协商自动进行身份验证,但如果通过 IP 连接则成功?
- C++为什么我的编译器成功了,但我的计算机给出了调试错误?
- 未知的 GCC 链接器错误,但已成功构建
- 我的 SonarQube C++扫描成功,但结果仅标记重复项,而没有标记其他标记的位置
- 为什么 LoadLibrary 失败,而 LoadLibraryA 成功加载 DLL?
- 是否有通用方法可以找到任何以 null 结尾的字符串的长度?
- 生成成功,但不会给出正确的输出
- 默认/样板代码在Visual Studio 2017中给我错误.E1574.虚幻.但构建成功了
- 即使不包含其标头,如何成功向前声明的类编译?
- C++成功复制动态分配的 obj 而不复制 ctor?
- 频率字长,程序只打开cmd,但不做任何事,c++