From 08a5918f4c18a74f1a545266a62bcc33e151e91b Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 1 Dec 2024 15:39:23 +0100 Subject: [PATCH] DetourHook: Add registerless longjump trampoline --- soup/CompactDetourHook.cpp | 6 +++--- soup/DetourHook.cpp | 6 +++--- soup/DetourHook.hpp | 2 +- soup/DetourHookBase.cpp | 27 +++++++++++++++++++-------- soup/DetourHookBase.hpp | 6 ++++-- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/soup/CompactDetourHook.cpp b/soup/CompactDetourHook.cpp index 0d5fe4f2..54f48a14 100644 --- a/soup/CompactDetourHook.cpp +++ b/soup/CompactDetourHook.cpp @@ -8,15 +8,15 @@ NAMESPACE_SOUP { void CompactDetourHook::create() { - memGuard::setAllowedAccess(code_cave, sizeof(longjump_trampoline), memGuard::ACC_RWX); - writeLongjumpTrampoline(code_cave, detour); + memGuard::setAllowedAccess(code_cave, sizeof(longjump_trampoline_r10), memGuard::ACC_RWX); + writeLongjumpTrampolineR10(code_cave, detour); createOriginal(sizeof(jmp_trampoline)); } void CompactDetourHook::destroy() { - memset(code_cave, 0xCC, sizeof(longjump_trampoline)); + memset(code_cave, 0xCC, sizeof(longjump_trampoline_r10)); destroyOriginal(); } diff --git a/soup/DetourHook.cpp b/soup/DetourHook.cpp index d8ccffd0..edc677e0 100644 --- a/soup/DetourHook.cpp +++ b/soup/DetourHook.cpp @@ -9,12 +9,12 @@ NAMESPACE_SOUP void DetourHook::enable() { void* addr = getEffectiveTarget(); - memGuard::setAllowedAccess(addr, sizeof(longjump_trampoline), memGuard::ACC_RWX); - writeLongjumpTrampoline(addr, detour); + memGuard::setAllowedAccess(addr, sizeof(longjump_trampoline_r10), memGuard::ACC_RWX); + writeLongjumpTrampolineR10(addr, detour); } void DetourHook::disable() { - memcpy(getEffectiveTarget(), original, sizeof(longjump_trampoline)); + memcpy(getEffectiveTarget(), original, sizeof(longjump_trampoline_r10)); } } diff --git a/soup/DetourHook.hpp b/soup/DetourHook.hpp index 3e86edbe..f3364551 100644 --- a/soup/DetourHook.hpp +++ b/soup/DetourHook.hpp @@ -7,7 +7,7 @@ NAMESPACE_SOUP struct DetourHook : public DetourHookBase { [[nodiscard]] bool isCreated() const noexcept { return original != nullptr; } - void create() { return createOriginal(sizeof(longjump_trampoline)); } + void create() { return createOriginal(sizeof(longjump_trampoline_r10)); } void destroy() noexcept { return destroyOriginal(); } void enable(); diff --git a/soup/DetourHookBase.cpp b/soup/DetourHookBase.cpp index 88734eba..f0b6d465 100644 --- a/soup/DetourHookBase.cpp +++ b/soup/DetourHookBase.cpp @@ -23,11 +23,16 @@ NAMESPACE_SOUP 0xE9, 0x00, 0x00, 0x00, 0x00, // jmp (4 bytes) }; - uint8_t DetourHookBase::longjump_trampoline[] = { + uint8_t DetourHookBase::longjump_trampoline_r10[] = { 0x49, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // movabs r10, (8 bytes) 0x41, 0xff, 0xe2, // jmp r10 }; + uint8_t DetourHookBase::longjump_trampoline_noreg[] = { + 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // (8 bytes) + }; + void* DetourHookBase::getEffectiveTarget() const { return Pointer(target).followJumps().as(); @@ -58,13 +63,13 @@ NAMESPACE_SOUP } } while (og_bytes < trampoline_bytes); - original = soup::malloc(og_bytes + sizeof(longjump_trampoline)); - memGuard::setAllowedAccess(original, og_bytes + sizeof(longjump_trampoline), memGuard::ACC_RWX); + original = soup::malloc(og_bytes + sizeof(longjump_trampoline_noreg)); + memGuard::setAllowedAccess(original, og_bytes + sizeof(longjump_trampoline_noreg), memGuard::ACC_RWX); memcpy(original, effective_target, og_bytes); - writeLongjumpTrampoline((uint8_t*)original + og_bytes, (uint8_t*)effective_target + og_bytes); + writeLongjumpTrampolineNoreg((uint8_t*)original + og_bytes, (uint8_t*)effective_target + og_bytes); #if DH_DEBUG - std::cout << "original proc: " << string::bin2hex(std::string((const char*)original, og_bytes + sizeof(longjump_trampoline))) << std::endl; + std::cout << "original proc: " << string::bin2hex(std::string((const char*)original, og_bytes + sizeof(longjump_trampoline_noreg))) << std::endl; #endif } @@ -89,9 +94,15 @@ NAMESPACE_SOUP memcpy(addr, jmp_trampoline, sizeof(jmp_trampoline)); } - void DetourHookBase::writeLongjumpTrampoline(void* addr, void* target) noexcept + void DetourHookBase::writeLongjumpTrampolineR10(void* addr, void* target) noexcept + { + *(void**)(longjump_trampoline_r10 + 2) = target; + memcpy(addr, longjump_trampoline_r10, sizeof(longjump_trampoline_r10)); + } + + void DetourHookBase::writeLongjumpTrampolineNoreg(void* addr, void* target) noexcept { - *(void**)(longjump_trampoline + 2) = target; - memcpy(addr, longjump_trampoline, sizeof(longjump_trampoline)); + *(void**)(longjump_trampoline_noreg + 6) = target; + memcpy(addr, longjump_trampoline_noreg, sizeof(longjump_trampoline_noreg)); } } diff --git a/soup/DetourHookBase.hpp b/soup/DetourHookBase.hpp index 19603a84..c49e33ff 100644 --- a/soup/DetourHookBase.hpp +++ b/soup/DetourHookBase.hpp @@ -14,13 +14,15 @@ NAMESPACE_SOUP void* original = nullptr; static uint8_t jmp_trampoline[5]; - static uint8_t longjump_trampoline[13]; + static uint8_t longjump_trampoline_r10[13]; + static uint8_t longjump_trampoline_noreg[14]; [[nodiscard]] void* getEffectiveTarget() const; void createOriginal(size_t trampoline_bytes); void destroyOriginal() noexcept; static void writeJmpTrampoline(void* addr, void* target); - static void writeLongjumpTrampoline(void* addr, void* target) noexcept; + static void writeLongjumpTrampolineR10(void* addr, void* target) noexcept; + static void writeLongjumpTrampolineNoreg(void* addr, void* target) noexcept; }; }