Hotpatching

This commit is contained in:
Guus Waals 2025-06-01 16:22:06 +08:00
parent e3c19e890f
commit 4092af3513
2 changed files with 36 additions and 10 deletions

View File

@ -96,6 +96,7 @@ function(setup_target TARGET DBG_MODE)
COMMAND ${gh_tool} -d${CMAKE_CURRENT_SOURCE_DIR}/gh.db
hooks -o ${CMAKE_CURRENT_BINARY_DIR}/hooks.def
)
target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_sources(${TARGET} PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/hooks.def

View File

@ -3,14 +3,21 @@
#include <windows.h>
#include <DbgHelp.h>
#include <memoryapi.h>
#include <hooker.h>
#define GH_BASE_ADDR 0x00400000
static uintptr_t g_gh_translationOffset{};
extern "C" {
#define HOOK(addr, name) void name(void *);
#include "hooks.def"
#undef HOOK
}
struct R3Bin {
R3Bin() { loadOriginal(); }
void loadOriginal() {
SPDLOG_DEBUG("Loading original binary");
@ -27,12 +34,15 @@ struct R3Bin {
uintptr_t(module) - GH_BASE_ADDR;
// Now we have to relocate the module to the new base address
relocateModule(module);
relocateModule();
patchFunctions();
}
inline void relocate(HMODULE module, void* instr, void* from, void* originalPointee) {
void* relocated_addr = (void*)(uintptr_t(from) + translationOffset);
void* relocated_to = (void*)(uintptr_t(originalPointee) + translationOffset);
inline void relocate(void *instr, void *from,
void *originalPointee) {
void *relocated_addr = (void *)(uintptr_t(from) + translationOffset);
void *relocated_to =
(void *)(uintptr_t(originalPointee) + translationOffset);
void *checkRead{};
SIZE_T numRead{};
ReadProcessMemory(GetCurrentProcess(), relocated_addr, &checkRead,
@ -40,12 +50,14 @@ struct R3Bin {
if (numRead != 4 || checkRead != originalPointee) {
throw std::logic_error("Invalid relocation");
}
WriteProcessMemory(GetCurrentProcess(), relocated_addr, &relocated_to, sizeof(relocated_to), NULL);
WriteProcessMemory(GetCurrentProcess(), relocated_addr, &relocated_to,
sizeof(relocated_to), NULL);
}
void relocateModule(HMODULE module) {
#define REL(instr, from, originalPointee) relocate(module, (void*)(instr), (void*)(from), (void*)(originalPointee));
#include "relocations.def"
void relocateModule() {
#define REL(instr, from, originalPointee) \
relocate((void *)(instr), (void *)(from), (void *)(originalPointee));
#include "relocations.def"
}
// Translate address relative from the original image base address
@ -148,6 +160,19 @@ struct R3Bin {
}
}
// Fixes up the target address (RVA) to jump into the patched function
void patchFunction(void *at, void *new_addr, const char *name) {
SPDLOG_DEBUG("Patching function {} at {}", name, at);
void *resolved = translateAddress(at);
if (!hooker_write_jmp(resolved, new_addr))
throw std::runtime_error(fmt::format(
"Failed to patch function {} at {} (RVA: {})", name, resolved, at));
}
void patchFunctions() {
#define HOOK(addr, name) patchFunction((void*)addr, &name, #name);
#include "hooks.def"
}
HINSTANCE module;
uintptr_t translationOffset;