diff --git a/game_re/CMakeLists.txt b/game_re/CMakeLists.txt index 22236e0e..e7710ff8 100644 --- a/game_re/CMakeLists.txt +++ b/game_re/CMakeLists.txt @@ -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 diff --git a/game_re/r3/binders/dbg_mem.cxx b/game_re/r3/binders/dbg_mem.cxx index dacb1aa3..a8e6fbe8 100644 --- a/game_re/r3/binders/dbg_mem.cxx +++ b/game_re/r3/binders/dbg_mem.cxx @@ -3,14 +3,21 @@ #include #include #include +#include #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;