#pragma once #define HOOK_JUMP true #define HOOK_CALL false namespace Utils { class Hook { public: Hook() : Place(nullptr), Stub(nullptr), Initialized(false), Installed(false), Original(0), UseJump(false), Protection(0) { ZeroMemory(Hook::Buffer, sizeof(Hook::Buffer)); } Hook(void* place, void* stub, bool useJump = true) : Hook() { Hook::Initialize(place, stub, useJump); } Hook(DWORD place, void* stub, bool useJump = true) : Hook(reinterpret_cast(place), stub, useJump) {} Hook(DWORD place, DWORD stub, bool useJump = true) : Hook(reinterpret_cast(place), reinterpret_cast(stub), useJump) {} Hook(DWORD place, void(*stub)(), bool useJump = true) : Hook(reinterpret_cast(place), reinterpret_cast(stub), useJump) {} ~Hook(); Hook* Initialize(void* place, void* stub, bool useJump = true); Hook* Initialize(DWORD place, void* stub, bool useJump = true); Hook* Initialize(DWORD place, void(*stub)(), bool useJump = true); // For lambdas Hook* Install(); Hook* Uninstall(); void* GetAddress(); void Quick(); template static std::function Call(DWORD function) { return std::function(reinterpret_cast(function)); } template static std::function Call(FARPROC function) { return Call(reinterpret_cast(function)); } static void SetString(void* place, const char* string, size_t length); static void SetString(DWORD place, const char* string, size_t length); static void SetString(void* place, const char* string); static void SetString(DWORD place, const char* string); static void Nop(void* place, size_t length); static void Nop(DWORD place, size_t length); static void RedirectJump(void* place, void* stub); static void RedirectJump(DWORD place, void* stub); template static void Set(void* place, T value) { DWORD oldProtect; VirtualProtect(place, sizeof(T), PAGE_EXECUTE_READWRITE, &oldProtect); *static_cast(place) = value; VirtualProtect(place, sizeof(T), oldProtect, &oldProtect); FlushInstructionCache(GetCurrentProcess(), place, sizeof(T)); } template static void Set(DWORD place, T value) { return Set(reinterpret_cast(place), value); } template static void Xor(void* place, T value) { DWORD oldProtect; VirtualProtect(place, sizeof(T), PAGE_EXECUTE_READWRITE, &oldProtect); *static_cast(place) ^= value; VirtualProtect(place, sizeof(T), oldProtect, &oldProtect); FlushInstructionCache(GetCurrentProcess(), place, sizeof(T)); } template static void Xor(DWORD place, T value) { return Xor(reinterpret_cast(place), value); } template static void Or(void* place, T value) { DWORD oldProtect; VirtualProtect(place, sizeof(T), PAGE_EXECUTE_READWRITE, &oldProtect); *static_cast(place) |= value; VirtualProtect(place, sizeof(T), oldProtect, &oldProtect); FlushInstructionCache(GetCurrentProcess(), place, sizeof(T)); } template static void Or(DWORD place, T value) { return Or(reinterpret_cast(place), value); } template static void And(void* place, T value) { DWORD oldProtect; VirtualProtect(place, sizeof(T), PAGE_EXECUTE_READWRITE, &oldProtect); *static_cast(place) &= value; VirtualProtect(place, sizeof(T), oldProtect, &oldProtect); FlushInstructionCache(GetCurrentProcess(), place, sizeof(T)); } template static void And(DWORD place, T value) { return And(reinterpret_cast(place), value); } template static T Get(void* place) { return *static_cast(place); } template static T Get(DWORD place) { return Get(reinterpret_cast(place)); } private: bool Initialized; bool Installed; void* Place; void* Stub; void* Original; char Buffer[5]; bool UseJump; DWORD Protection; std::mutex StateMutex; }; }