监视所有线程的 SetWindowsHookEx():挂钩过程必须位于 DLL 中

SetWindowsHookEx() monitoring all threads: Must the hook procedure be located in a DLL?

本文关键字:过程 DLL 线程 SetWindowsHookEx 监视      更新时间:2023-10-16

SetWindowsHookEx(( 监视所有线程:钩子过程必须位于 DLL 中吗?

我很困惑用于监视所有线程的钩子过程是否必须位于 DLL 中。

如下面的教程所示,指出钩子过程不需要位于 DLL 中。

http://www.unknowncheats.me/forum/c-and-c/83707-setwindowshookex-example.html

我是不是误会了什么?

  if (!(_hook = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0)))

这并非大错特错。 这两个低级挂钩与所有其他挂钩不同,Windows 在将键盘或鼠标消息调度到拥有前台窗口的进程之前,会在进程中调用挂钩回调。 不需要也不使用 DLL。 你确实需要抽取一个消息循环(GetMessage/DispatchMessage(,Windows只有在知道你的线程处于空闲状态并准备好执行代码时才能进行回调。

从 Windows 7 SP1 开始,可以为第三个参数传递 NULL。 错误修复,以前的版本需要有效的 DLL 句柄,验证了它,但实际上并没有使用它。 提供一个并因此确保您的代码与任何Windows版本兼容的最佳方法是使用您从LoadLibrary(L"user32.dll"(获得的代码。

请注意与WH_KEYBOARD钩子的区别,钩子确实需要 DLL。 最大的区别在于它的回调更可靠,因为它在进程中运行,它知道进程的键盘状态。 GetKeyState(( 是准确的,没有办法在WH_KEYBOARD_LL钩子中完成相同的任务。 如果你需要钩住每个进程,那么今天编写这样的钩子是非常痛苦的,UAC 抛出了一个障碍(除非你自己被提升,否则你不能注入一个提升的进程(,以及需要编写一个 32 位和 64 位版本的钩子程序和 DLL。

您链接到的论坛主题是错误的。那里的代码使用 WH_KEYBOARD_LL 钩子、空模块和零线程 ID(全局(调用SetWindowsHookEx

MSDN for SetWindowsHookEx 声明:

如果 hMod 参数为 NULL 且 dwThreadId 参数为零或指定由另一个进程创建的线程的标识符,则可能会发生错误。

没有详细说明错误何时会发生,但我不会依赖它不会发生。来自论坛线程的调用显然违反了此处的限制。

再往下看,MSDN 指出:

所有全局钩子函数都必须在库中。

从来没有明确说明全局钩子函数是什么,但强烈暗示这意味着线程 ID 为 0。此外,低级键盘挂钩只能作为全局安装。

这意味着论坛线程中显示的钩子函数必须位于 DLL 中,任何相反的语句都是不正确的。

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx