使用UnhookWindowsHookEx()取消连接时,有几个程序崩溃

时间:2015-11-14 22:07:49

标签: c++ windows winapi detours

我正在做一个全局钩子,将我的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);
}

有人可以帮助我理解为什么会这样,以及我如何解决这个问题?谢谢!

2 个答案:

答案 0 :(得分:2)

您正在绕开几乎所有流程都使用的功能。并且特别危险,因为这样的进程很可能对该函数的调用有效。几乎在任何情况下都是阻止呼叫。一旦解锁,代码就会恢复到您不再存在的绕行路线。

KABOOM。

实际上,卸载绕道的唯一方法是退出,以便每个可能绕道而行的过程不再运行。

答案 1 :(得分:1)

我认为这种情况正在发生,因为许多程序(Chrome,Skype,...)都有一个线程池,后台线程[s]正在WaitForSingleObject()上等待它们发生的有趣事情,以及它何时发生,那个线程醒来并做点什么。

因此,您的线程A正在调用DetourDetach,而同一进程的另一个线程B当前位于Mine_WaitForSingleObject()内,然后DLL卸载,一切都崩溃了。您可以使用调试器进行验证,附加到有问题的进程,在DLL_PROCESS_DETACH中设置断点,当断点发生时,查看Mine_WaitForSingleObject的其他线程的堆栈。

我不确定如何解决。 但是,您可以尝试一种方法 - 枚举线程,并为进程的每个线程调用DetourUpdateThread()。这样,也许Detours会为此做些什么。