在其他人之前处理我的WindowsHook

时间:2017-10-19 00:18:26

标签: c++ windows winapi hook

我在谷歌和微软的钩子文档上搜索过,我找到了很多如何制作钩子,但我已经知道如何做到这一点。如何使我的钩子(在这种情况下是键盘钩子)首先在队列中接收消息?我试图让我的钩子尽可能接近硬件输入,以防止另一个键钩改变输入。 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(所以我的钩子永远不会得到它)或它欺骗它。

2 个答案:

答案 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功能向游戏中注入假的击键。