#pragma once #include "types.h" #if _M_IX86 #define OFFSET_TO_ADDRESS 0x1 #elif _M_X64 #define OFFSET_TO_ADDRESS 0x2 #endif inline void write_to_readonly(void* addr, void* data, int size) { if(!addr || !data || !size) return; { // // disable write protection. // auto cr0 = __readcr0(); cr0 &= 0xfffffffffffeffff; __writecr0(cr0); _disable(); } memcpy(addr, data, size); { // // enable write protection. // auto cr0 = __readcr0(); cr0 |= 0x10000; _enable(); __writecr0(cr0); } } class detour { public: detour() {}; detour(void* addr_to_hook, void* jmp_to, bool enable = true) : hook_addr(addr_to_hook), detour_addr(jmp_to), hook_installed(false) { init(addr_to_hook, jmp_to, enable); } void init(void* addr_to_hook, void* jmp_to, bool enable = true) { //setup hook memcpy( jmp_code + OFFSET_TO_ADDRESS, &jmp_to, sizeof(jmp_to) ); //save bytes memcpy( org_bytes, hook_addr, sizeof(org_bytes) ); if (enable) install(); } void install() { if (hook_installed) return; write_to_readonly(hook_addr, jmp_code, sizeof(jmp_code)); hook_installed = true; } void uninstall() { if (!hook_installed) return; write_to_readonly(hook_addr, org_bytes, sizeof(org_bytes)); hook_installed = false; } bool installed() { return hook_installed; } void* hook_address() { return hook_addr; } void* detour_address() { return detour_addr; } private: bool hook_installed; void* hook_addr, * detour_addr; #if _M_IX86 /* 0: b8 ff ff ff ff mov eax, 0xffffffff 5: ff e0 jmp eax */ unsigned char jmp_code[7] = { 0xb8, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xE0 }; #elif _M_X64 /* 0: 48 c7 c0 ff ff ff ff mov rax,0xffffffffffffffff 7: ff e0 jmp rax */ unsigned char jmp_code[12] = { 0x48, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xe0 }; #endif unsigned char org_bytes[sizeof(jmp_code)]; };