Hotpatching
This commit is contained in:
parent
e3c19e890f
commit
4092af3513
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue