osu-auth-reader/ac_checker/source/util/hooklib.cpp
2022-09-29 12:31:39 +02:00

76 lines
2.2 KiB
C++

#include <Windows.h>
#include <util/hooklib.hpp>
#include <vendor/hde.hpp>
namespace util {
constexpr uint8_t target_shellcode[] = {
0x8D, 0x64, 0x24, 0xFC, // lea esp, [esp-0x4]
0xC7, 0x04, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, // mov DWORD PTR [esp], ADDRESS
0xC3 // ret
};
constexpr uint8_t tramp_shellcode[] = {
0x68, 0xFF, 0xFF, 0xFF, 0xFF, // push imm32
0xC3, // ret
};
bool Hook::enable(uintptr_t target, uintptr_t detour) {
hde32s hde_state;
while (_bytes < sizeof(target_shellcode)) {
_bytes += hde32_disasm((const void *) (target + _bytes), &hde_state);
if (hde_state.opcode == 0xC3) {
_bytes = 0;
return false;
}
}
auto tramp = VirtualAlloc(nullptr, _bytes + sizeof(tramp_shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!tramp) {
_bytes = 0;
return false;
}
unsigned long old_prot;
VirtualProtect((void *) target, _bytes, PAGE_EXECUTE_READWRITE, &old_prot);
_target = target;
_detour = detour;
_tramp = (uintptr_t) tramp;
memcpy((uint8_t *) _tramp, (const uint8_t *) _target, _bytes);
memcpy((uint8_t *) _tramp + _bytes, tramp_shellcode, sizeof(tramp_shellcode));
memcpy((uint8_t *) _target, target_shellcode, sizeof(target_shellcode));
*(uintptr_t *) (_target + 7) = _detour;
*(uintptr_t *) (_tramp + _bytes + 1) = _target + _bytes;
VirtualProtect((void *) target, _bytes, old_prot, &old_prot);
return true;
}
void Hook::disable() {
if (!_bytes)
return;
unsigned long old_prot;
VirtualProtect((void *) _target, _bytes, PAGE_EXECUTE_READWRITE, &old_prot);
memcpy((uint8_t *) _target, (const uint8_t *) _tramp + _bytes, _bytes);
VirtualFree((void *) _tramp, 0, MEM_RELEASE);
VirtualProtect((void *) _target, _bytes, old_prot, &old_prot);
_bytes = 0;
_target = 0;
_detour = 0;
_tramp = 0;
}
} // namespace util