我在谷歌和微软的钩子文档上搜索过,我找到了很多如何制作钩子,但我已经知道如何做到这一点。如何使我的钩子(在这种情况下是键盘钩子)首先在队列中接收消息?我试图让我的钩子尽可能接近硬件输入,以防止另一个键钩改变输入。 I.E:App1运行一个关键钩子来欺骗KBDLLHOOK的标志,使其不被注入。如何在从LLKHF_INJECTED更改标志之前获取该消息?
TL; DR我的钩子如何在另一个之前获取消息以防止密钥注入?
我用来测试的简单代码
LRESULT CALLBACK keybdProc(int n, WPARAM w, LPARAM l)
{
KBDLLHOOKSTRUCT *kbdll = (KBDLLHOOKSTRUCT*)l;
if (w == WM_KEYDOWN)
{
switch (kbdll->flags)
{
case LLKHF_INJECTED:
printf("%d/%c is an Injected Key Press (Reject)\n", kbdll->vkCode, char(kbdll->vkCode));
break;
default:
printf("%d/%c Not injected (Continue)\n", kbdll->vkCode, char(kbdll->vkCode));
break;
}
}
return 0; //CallNextHookEx(NULL, n, w, l);
}
int main()
{
HHOOK keybdHk = SetWindowsHookEx(WH_KEYBOARD_LL, keybdProc, GetModuleHandle(NULL), 0);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(keybdHk);
return 0;
}
编辑:我知道消息队列按顺序排在倒数第一顺序,但无论如何,无论我在App1之前还是之后启动我的程序,它仍然在我的Keyhook之前得到输入,然后不调用NextHook(所以我的钩子永远不会得到它)或它欺骗它。
答案 0 :(得分:1)
钩子在hook chains中管理,钩子程序从前到后按顺序执行。正如documented:
SetWindowsHookEx函数总是在钩子链的开头安装一个钩子程序。当发生由特定类型的钩子监视的事件时,系统在与钩子相关联的钩子链的开头调用该过程。链中的每个钩子过程确定是否将事件传递给下一个过程。
要首先调用您的钩子,需要最后安装它。虽然这很容易确定,但在钩链中保持这个位置是不可能的。
答案 1 :(得分:0)
两件事。
从Windows 10开始,在KBDLLHOOKSTRUCT
参数中收到的结构lParam
无法再进行修改。即使您调用CallNextHookEx(NULL, code, wParam, lParam)
,对它所做的更改也不会传递到下一个挂钩过程。
您甚至可以将完全不同的lParam
指针传递给CallNextHookEx
,但是随后的钩子仍将接收未经修改的原始结构。
从未记录过修改KBDLLHOOKSTRUCT
的能力,但在以前版本的window中确实可以实现。但是,不再。
但是,您仍然可以通过不调用CallNextHookEx
来阻止其他挂钩过程接收输入消息。
避免其他进程干扰您看到的输入的适当方法是使用Raw Input API。
您可以使用函数RegisterRawInputDevices
,以便您的进程直接从设备接收输入。无论如何,其他进程都无法阻止,篡改或更改您从此API获得的收益。
使用Raw Input,您甚至可以检测哪个特定的键盘发送了给定的击键(以防插入了多个键盘),这无法使用键盘挂钩实现。
这是游戏检测输入的方式,以便用户无法使用SendInput
功能向游戏中注入假的击键。