#pragma once #include #include #include #define JMP_CODE_SIZE 14 #define OFFSET_TO_ADDRESS 0x2 namespace Hook { class Detour { public: Detour(uintptr_t addrToHook, uintptr_t jmpTo); ~Detour(); void InstallHook(); void UninstallHook(); bool IsInstalled(); uintptr_t GetHookAddress(); uintptr_t GetDetourAddress(); private: bool isHookInstalled{ false }; uintptr_t HookAddress, DetourAddress; unsigned char jmpCode[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 originalBytes[JMP_CODE_SIZE]; }; static std::map> hooks{}; __forceinline void WriteToReadOnly(uintptr_t addr, void* data, int size) { DWORD oldFlags; VirtualProtect((LPVOID)addr, size, PAGE_READWRITE, &oldFlags); memcpy((void*)addr, data, size); VirtualProtect((LPVOID)addr, size, oldFlags, &oldFlags); } /* Author: xerox Date: 12/19/2019 Create Hook without needing to deal with objects */ __forceinline void Install(uintptr_t addrToHook, uintptr_t jmpToAddr) { if (!addrToHook) return; hooks.insert({ addrToHook, std::make_unique( addrToHook, jmpToAddr )} ); } /* Author: xerox Date: 12/19/2019 Enable hook given the address to hook */ __forceinline void Enable(uintptr_t addr) { if (!addr) return; hooks.at(addr)->InstallHook(); } /* Author: xerox Date: 12/19/2019 Disable hook givent the address of the hook */ __forceinline void Disable(uintptr_t addr) { if (!addr) return; hooks.at(addr)->UninstallHook(); } /* Author: xerox Date: 12/19/2019 Remove hook completely from vector */ __forceinline void Remove(uintptr_t addr) { if (!addr) return; hooks.erase(addr); } }