当钩子启动一个新线程时取消挂钩一个钩子进程

Unhooking a hooked process when the hook starts a new thread

我创建了一个简单的挂钩,并随

安装
SetWindowsHookEx(WH_CBT, addr, dll, 0);

完成后,我使用

卸载
UnhookWindowsHookEx(0);

然后我可以看到注入的 DLL 从被调用的注入 DLL 的 DllMain 中的钩子进程中卸载

DllMain(..., DLL_PROCESS_DETACH, ...)

但是,如果我注入的 DLL 像这样启动一个简单的线程:

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
...
    static bool alreadyHooked = false;
    switch (nCode)
    {
    case HCBT_ACTIVATE:
    {
        if (alreadyHooked)
        {
            break;
        }
        alreadyHooked = true;
        std::thread([&]
        {
            for (;;)
            {
                Sleep(1000);
            }
        }).detach();
    }
}

然后注入的 DLL 不会卸载。 运行 线程使其继续运行。

要卸载 DLL,我有哪些选择?我可以使用 IPC 让所有挂钩的进程知道是时候在我调用 UnhookWindowsHookEx() 时关闭额外的线程了,但这感觉有点多余,因为已经通过 UnhookWindowsHookEx() 进行了一些通信。

除了 IPC 之外,是否有其他方法可以在挂钩进程中发现 UnhookWindowsHookEx() 已被调用,然后彻底关闭我启动的所有线程?旋转阻止 dll 卸载的线程,但使用 Minhook 拼接我的 dll 代码等其他事情却没有?

我刚才问过这个问题,@Hans Passant 基本上在评论中回答了它,但由于没有官方回答,它被自动删除了。觉得很值得带回一个答案。

Hans 从 MS documentation on hooking 中指出:

The system eventually frees the DLL after all processes explicitly linked to the DLL have either terminated or called FreeLibrary and all processes that called the hook procedure have resumed processing outside the DLL.

所以基本上,是的,从挂钩程序到挂钩程序的 IPC 通信是时候卸载并且需要停止线程旋转是完成此操作的唯一方法。谢谢汉斯。