Untitled
unknown
plain_text
9 months ago
2.9 kB
18
Indexable
#include <Windows.h>
#include <cstdint>
#include <memory>
#include <cstring>
namespace StealthHook {
struct HookContext {
BYTE originalBytes[16];
void* target;
void* detour;
void* trampoline;
size_t patchSize;
};
void* AllocTrampoline(size_t size) {
return VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
bool PlaceJMP(void* target, void* detour, BYTE* original, size_t len) {
if (len < 5) return false;
DWORD oldProtect;
VirtualProtect(target, len, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(original, target, len);
#ifdef _WIN64
if (std::abs((int64_t)detour - (int64_t)target) > 0x7FFFFFFF) {
BYTE patch[14] = {
0x48, 0xB8,
0, 0, 0, 0, 0, 0, 0, 0,
0xFF, 0xE0
};
memcpy(patch + 2, &detour, 8);
memcpy(target, patch, 14);
VirtualProtect(target, len, oldProtect, &oldProtect);
return true;
}
#endif
uintptr_t relAddr = (uintptr_t)detour - (uintptr_t)target - 5;
BYTE patch[16] = { 0xE9 };
memcpy(patch + 1, &relAddr, 4);
memcpy(target, patch, len);
VirtualProtect(target, len, oldProtect, &oldProtect);
return true;
}
bool CreateHook(void* target, void* detour, HookContext& ctx, size_t patchLen = 5) {
if (!target || !detour || patchLen < 5 || patchLen > sizeof(ctx.originalBytes)) return false;
ctx.target = target;
ctx.detour = detour;
ctx.patchSize = patchLen;
memcpy(ctx.originalBytes, target, patchLen);
ctx.trampoline = AllocTrampoline(patchLen + 5);
if (!ctx.trampoline) return false;
memcpy(ctx.trampoline, ctx.originalBytes, patchLen);
uintptr_t jumpBack = (uintptr_t)target + patchLen;
BYTE jmpBack[5] = { 0xE9 };
uintptr_t rel = jumpBack - ((uintptr_t)ctx.trampoline + patchLen) - 5;
memcpy(jmpBack + 1, &rel, 4);
memcpy((BYTE*)ctx.trampoline + patchLen, jmpBack, 5);
DWORD trampProtect;
VirtualProtect(ctx.trampoline, patchLen + 5, PAGE_EXECUTE_READ, &trampProtect);
return PlaceJMP(target, detour, ctx.originalBytes, patchLen);
}
void RemoveHook(HookContext& ctx) {
if (!ctx.target) return;
DWORD oldProtect;
VirtualProtect(ctx.target, ctx.patchSize, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(ctx.target, ctx.originalBytes, ctx.patchSize);
VirtualProtect(ctx.target, ctx.patchSize, oldProtect, &oldProtect);
}
template<typename T>
T GetOriginal(HookContext& ctx) {
return reinterpret_cast<T>(ctx.trampoline);
}
} // namespace StealthHookEditor is loading...
Leave a Comment