【发布时间】:2017-12-08 12:56:12
【问题描述】:
我已经编写了一个程序(.DLL),将被注入到 process.exe 中。
DLL 注入器代码:
Bool InjectDll(DWORD pID, const char* dllPath) {
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (!Proc)
{
return false;
}
void* LoadLibAddr = (void*)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
void* RemoteString = (void*)VirtualAllocEx(Proc, NULL, strlen(dllPath), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, dllPath, strlen(dllPath), NULL);
HANDLE ret = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, (LPVOID)RemoteString, CREATE_SUSPENDED, NULL);
if (ret) {
return true;
}
}
要注入的.DLL的DllMain()函数:
#include <Windows.h>
extern void vMain();
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&vMain, 0, 0, 0);
return true;
}
return false;
}
vMain:
void vMain() {
CreateConsole();
std::cout << "vMain() has executed!\n";
}
当我在 Visual Studio 中编译要注入的 .DLL 时,它工作正常,但是当我在 QT Creator 中编译时,vMain() 永远不会被执行。注入器、.DLL 和目标进程都是 32 位的。因此,我尝试通过使用CREATE_SUSPENDED 标志使.DLL 注入器调用CreateRemoteThread() 来调试目标进程,这样我就可以在LoadLibraryA() 上设置断点,恢复线程,从断点逐步执行,然后查看返回值。但是,我在 LoadLibraryA() 上的断点没有被命中。
所以我调试了 .DLL 注入器应用程序以确保正在创建远程线程。我确认是通过在CreateRemoteThread()的返回值上调用GetThreadID(),将其输出,并在目标进程的线程列表中查看该线程:
请记住,线程仍处于挂起状态。进一步检查,EIP 指向_RtlUserThreadStart() 中的第一条指令。我在这条指令上设置了一个断点。然后我通过从我的 .DLL 注入程序中调用 ResumeThread() 来恢复挂起的线程。没有命中断点。
值得注意的是,目标应用程序没有任何反断点机制,除了这个实例之外,断点对我来说都很好。
那么我怎样才能找出问题所在呢?我的断点没有被击中是有原因的吗?有没有更好的方法来调试问题?
【问题讨论】:
-
dllPath是完整路径吗?如果不是,那么您确定从 Qt Creator 运行时可以访问它吗?
标签: c++ qt debugging dll dll-injection