SetWindowsHookEx()监视所有线程:钩子程序必须位于DLL中吗?
我很困惑用于监视所有线程的钩子过程是否必须位于DLL中。
如下面的教程所示,声明钩子过程不需要位于DLL中。
http://www.unknowncheats.me/forum/c-and-c/83707-setwindowshookex-example.html
我误解了什么吗?
答案 0 :(得分:5)
if (!(_hook = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0)))
这不是非常错误的。两个低级钩子与其他所有钩子不同,Windows在将键盘或鼠标消息发送到拥有前台窗口的进程之前调用您的进程中的钩子回调。不需要也不使用DLL。你做需要抽一个消息循环(GetMessage / DispatchMessage),Windows只能在知道你的线程空闲并准备执行代码时才进行回调。
从Windows 7 SP1开始,可以为第3个参数传递NULL。一个错误修复,以前的版本需要一个有效的DLL句柄,验证它但实际上没有使用它。提供一个并确保您的代码与任何Windows版本兼容的最佳方法是使用从LoadLibrary(L“user32.dll”)获得的代码。
请注意与WH_KEYBOARD挂钩的区别, 需要DLL的挂钩。最大的区别在于它的回调更可靠,因为它在进程中运行它知道进程的键盘状态。 GetKeyState()是准确的,没有办法在WH_KEYBOARD_LL钩子中完成相同的操作。如果你需要挂钩每个进程,写一个这样的钩子是非常痛苦的,UAC会引发一个障碍(除非你自己提升,否则不能注入提升的进程)以及编写32位和64位的需要你的挂钩程序和DLL的位版本。
答案 1 :(得分:0)
您链接的论坛帖子是错误的。那里的代码使用SetWindowsHookEx
钩子,空模块和零线程id(全局)调用WH_KEYBOARD_LL
。
SetWindowsHookEx
州的MSDN:
如果hMod参数为NULL并且dwThreadId参数为零或指定由另一个进程创建的线程的标识符,则可能发生错误。
没有详细说明何时会发生错误,但我不会依赖它不会发生。来自论坛帖子的电话明显违反了这里的限制。
再向下,MSDN声明:
所有全局钩子函数都必须在库中。
从未明确说明全局钩子函数是什么,但强烈暗示这意味着线程ID为0.此外,低级别键盘钩子只能安装为全局。
这意味着论坛帖子中提供的钩子函数必须在一个DLL中,而任何相反的陈述都是错误的。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx