Skip to content

Commit

Permalink
Clean up input hook code
Browse files Browse the repository at this point in the history
This cleans up the input hooking code with better comments, use of
nullptr instead of 0, and more accurate error handling.

The "more accurate error handling" is that previously if one hook was
registered and the other one was not then the message pump would not
be run, which could cause issues.
  • Loading branch information
randomascii committed Jul 28, 2023
1 parent 88afed6 commit fd4d0f3
Showing 1 changed file with 38 additions and 25 deletions.
63 changes: 38 additions & 25 deletions UIforETW/KeyLoggerThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ LRESULT CALLBACK LowLevelKeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
ETWKeyDown(code, keyDownDetails.c_str(), 0, 0);
}

return CallNextHookEx(0, nCode, wParam, lParam);
return CallNextHookEx(nullptr, nCode, wParam, lParam);
}

_Pre_satisfies_(nCode == HC_ACTION)
Expand Down Expand Up @@ -228,7 +228,7 @@ LRESULT CALLBACK LowLevelMouseHook(int nCode, WPARAM wParam, LPARAM lParam) noex
}
}

return CallNextHookEx(0, nCode, wParam, lParam);
return CallNextHookEx(nullptr, nCode, wParam, lParam);
}


Expand All @@ -252,30 +252,43 @@ DWORD __stdcall InputThread(LPVOID) noexcept
// processed in a timely manner or else bad things will happen. Doing this on a
// separate thread is a good idea, but even then bad things will happen to your system
// if you halt in a debugger. Even simple things like calling printf() from the hook
// can easily cause system deadlocks which render the mouse unable to move!
HHOOK keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardHook, NULL, 0);
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseHook, NULL, 0);

if (!keyHook && !mouseHook)
return 0;

// Run a message pump -- necessary so that the hooks will be processed
BOOL bRet;
MSG msg;
// Keeping pumping messages until WM_QUIT is received. If this is opened
// in a child thread then you can terminate it by using PostThreadMessage
// to send WM_QUIT.
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
// can easily cause system deadlocks which cause all input to be processed
// very slowly.
// The default OS hook timeout seems to be 300 ms, which is long enough to
// make input delays noticeable, but short enough to make the system sort of
// usable. You can set a shorter timeout (10 ms in this case) with this
// command:
// reg add "HKCU\Control Panel\Desktop" /v LowLevelHooksTimeout /t REG_DWORD /f /d 10
// Occasional input delays were, in one case, tracked down to an input hook
// (unknown owner) that was briefly timing out. Twitter discussion is here:
// https://twitter.com/BruceDawson0xB/status/1673375468127670273
HHOOK keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardHook, nullptr, 0);
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseHook, nullptr, 0);

// Run the message pump if either hook is successfully registered (they should
// always both be registered).
if (keyHook || mouseHook)
{
if (bRet == -1)
{
// handle the error and possibly exit
break;
}
else
// Run a message pump -- necessary so that the hooks will be processed
BOOL bRet;
MSG msg;
// Keeping pumping messages until WM_QUIT is received. If this is running
// in a child thread then you can terminate it by using PostThreadMessage
// to send WM_QUIT.
while ((bRet = GetMessageW(&msg, nullptr, 0, 0)) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
// GetMessageW will normally only return when WM_QUIT is received, so this
// loop normally doesn't ever run.
if (bRet == -1)
{
// Unexpected error. Quit.
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}

Expand Down Expand Up @@ -312,7 +325,7 @@ void SetKeyloggingState(enum KeyLoggerState state) noexcept
// it isn't running.
if (!s_hThread)
{
s_hThread = CreateThread(NULL, 0, InputThread, NULL, 0, &s_threadID);
s_hThread = CreateThread(nullptr, 0, InputThread, nullptr, 0, &s_threadID);
}

switch (state)
Expand Down

0 comments on commit fd4d0f3

Please sign in to comment.