#pragma once #include #include #include #define JMP_CODE_SIZE 14 #define OFFSET_TO_ADDRESS 0x2 namespace hook { class detour { public: detour(void* addrToHook, void* jmpTo); ~detour(); void install(); void uninstall(); bool installed(); uintptr_t hook_address(); uintptr_t detour_address(); private: bool hook_installed{ false }; uintptr_t hook_addr, detour_addr; unsigned char jmp_code[JMP_CODE_SIZE] = { 0x48, 0xb8, //movabs rax, &jmpTo 0x0, //jmpTo address will be here in these 0's 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xe0, //jmp rax 0x90, 0x90 //nop, nop }; char org_bytes[JMP_CODE_SIZE]; }; static std::map> hooks{}; __forceinline void write_to_readonly(void* addr, void* data, int size) { DWORD old_flags; VirtualProtect((LPVOID)addr, size, PAGE_READWRITE, &old_flags); memcpy((void*)addr, data, size); VirtualProtect((LPVOID)addr, size, old_flags, &old_flags); } /* Author: xerox Date: 12/19/2019 Create Hook without needing to deal with objects */ __forceinline void install(void* addr_to_hook, void* jmp_to_addr) { if (!addr_to_hook) return; hooks.insert({ (std::uintptr_t)addr_to_hook, std::make_unique( addr_to_hook, jmp_to_addr )} ); } /* Author: xerox Date: 12/19/2019 Enable hook given the address to hook */ __forceinline void enable(void* addr) { if (!addr) return; hooks.at((std::uintptr_t)addr)->install(); } /* Author: xerox Date: 12/19/2019 Disable hook givent the address of the hook */ __forceinline void disable(void* addr) { if (!addr) return; hooks.at((std::uintptr_t)addr)->uninstall(); } /* Author: xerox Date: 12/19/2019 Remove hook completely from vector */ __forceinline void remove(void* addr) { if (!addr) return; hooks.erase((std::uintptr_t)addr); } }