Skip to content

Implementation of hooks is incorrect if other software hooks functions after Windower #30

@Kaldaien

Description

@Kaldaien

It is unlikely that you can do anything about this, but I thought I'd point out a serious flaw in nearly all of the hooks:

::HHOOK WINAPI SetWindowsHookExW(
int idHook, ::HOOKPROC lpfn, ::HINSTANCE hMod, ::DWORD dwThreadId) noexcept
{
if ((idHook == WH_KEYBOARD_LL || idHook == WH_KEYBOARD) &&
windower::is_game_module(WINDOWER_RETURN_ADDRESS))
{
return std::bit_cast<::HHOOK>(
std::bit_cast<std::intptr_t>(windower::windower_module()) +
::InterlockedIncrement(&hhook_counter));
}
return hooks::SetWindowsHookExW(idHook, lpfn, hMod, dwThreadId);
}
::BOOL WINAPI UnhookWindowsHookEx(::HHOOK hhk) noexcept
{
if (windower::is_windower_module(hhk))
{
return TRUE;
}
return hooks::UnhookWindowsHookEx(hhk);
}

windower::is_game_module(WINDOWER_RETURN_ADDRESS)

That assumes that the return address from your hook is always the thing that originally called the function. However, if another DLL hooks SetWindowsHookW after you do, then the return address is the other DLL. The return address of the other DLL's hook, assuming no other hooks, is the original caller.

You can't implement this thing this way, without properly walking the call stack to compensate for other hook libraries (i.e. ReShade), this is a disaster waiting to happen. Said disaster has occurred with ReShade 6.4.0, the mod no longer blocks keyboard input correctly.

Other things were broken before ReShade 6.4.0, but more subtly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions