Skip to content

Commit

Permalink
DetourHook: Add registerless longjump trampoline
Browse files Browse the repository at this point in the history
  • Loading branch information
Sainan committed Dec 1, 2024
1 parent e79adc7 commit 08a5918
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 17 deletions.
6 changes: 3 additions & 3 deletions soup/CompactDetourHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
6 changes: 3 additions & 3 deletions soup/DetourHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
2 changes: 1 addition & 1 deletion soup/DetourHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
27 changes: 19 additions & 8 deletions soup/DetourHookBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<void*>();
Expand Down Expand Up @@ -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
}

Expand All @@ -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));
}
}
6 changes: 4 additions & 2 deletions soup/DetourHookBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
}

0 comments on commit 08a5918

Please sign in to comment.