我正在做一个全局钩子,将我的DLL添加到钩子链中:
HHOOK handle = SetWindowsHookEx(WH_CALLWNDPROC, addr, dll, 0);
在我的DLL中,我使用Detours来拦截几个WINAPI函数调用。一切正常,但WaitForSingleObject调用除外。每当我将WaitForSingleObject添加到绕行函数时,当我解开我的DLL(Chrome,Skype,...)时,几个程序都会崩溃。 这是DLL的外观:
DWORD (WINAPI* Real_WaitForSingleObject)( HANDLE hHandle, DWORD dwMilliseconds) = WaitForSingleObject;
DWORD WINAPI Mine_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
switch(Reason) {
case DLL_PROCESS_ATTACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_WaitForSingleObject, Mine_WaitForSingleObject);
DetourTransactionCommit();
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_WaitForSingleObject, Mine_WaitForSingleObject);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
DWORD WINAPI Mine_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
return Real_WaitForSingleObject(hHandle, dwMilliseconds);
}
extern "C" __declspec(dllexport) int meconnect(int code, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(NULL, code, wParam, lParam);
}
有人可以帮助我理解为什么会这样,以及我如何解决这个问题?谢谢!
答案 0 :(得分:2)
您正在绕开几乎所有流程都使用的功能。并且特别危险,因为这样的进程很可能对该函数的调用有效。几乎在任何情况下都是阻止呼叫。一旦解锁,代码就会恢复到您不再存在的绕行路线。
KABOOM。
实际上,卸载绕道的唯一方法是退出,以便每个可能绕道而行的过程不再运行。
答案 1 :(得分:1)
我认为这种情况正在发生,因为许多程序(Chrome,Skype,...)都有一个线程池,后台线程[s]正在WaitForSingleObject()上等待它们发生的有趣事情,以及它何时发生,那个线程醒来并做点什么。
因此,您的线程A正在调用DetourDetach,而同一进程的另一个线程B当前位于Mine_WaitForSingleObject()内,然后DLL卸载,一切都崩溃了。您可以使用调试器进行验证,附加到有问题的进程,在DLL_PROCESS_DETACH中设置断点,当断点发生时,查看Mine_WaitForSingleObject的其他线程的堆栈。
我不确定如何解决。 但是,您可以尝试一种方法 - 枚举线程,并为进程的每个线程调用DetourUpdateThread()。这样,也许Detours会为此做些什么。