#pragma once #include #include #include namespace Vook { inline std::uint8_t* PatternScan(const HMODULE Module, const char* Signature) { [[unlikely]] if (!Module) return {}; static auto PatternToBytes = [](const char* Pattern) { auto Bytes = std::vector{}; char* StartPos = const_cast(Pattern); char* EndPos = const_cast(Pattern) + std::strlen(Pattern); for (auto CurrentChar = StartPos; CurrentChar < EndPos; ++CurrentChar) { if (*CurrentChar == '?') { ++CurrentChar; if (*CurrentChar == '?') ++CurrentChar; Bytes.push_back(-1); } else Bytes.push_back(std::strtoul(CurrentChar, &CurrentChar, 16)); } return Bytes; }; const IMAGE_DOS_HEADER* DosHeader = reinterpret_cast(Module); const IMAGE_NT_HEADERS* NtHeaders = reinterpret_cast(reinterpret_cast(Module) + DosHeader->e_lfanew); auto PatternBytes = PatternToBytes(Signature); const std::size_t PatternBytesSize = PatternBytes.size(); const int* PatternBytesData = PatternBytes.data(); const auto ImageSize = NtHeaders->OptionalHeader.SizeOfImage; std::uint8_t* ScanBytes = reinterpret_cast(Module); for (unsigned long i = 0; i < ImageSize - PatternBytesSize; ++i) { bool Found = true; for (unsigned long j = 0; j < PatternBytesSize; ++j) { if (ScanBytes[i + j] != PatternBytesData[j] && PatternBytesData[j] != -1) { Found = false; break; } } [[unlikely]] if (Found) return &ScanBytes[i]; } return {}; } #ifdef _WIN64 // char __fastcall ValveHookWrapper(void *FnAddr, __int64 HkAddr, _QWORD *OgAddr, int PreserveLogs) using FnValveHook = char(__fastcall*)(void*, void*, void*, int); #else // char __cdecl ValveHook(LPVOID FnAddr, int HkAddr, int OgAddr, int PreserveLogs) using FnValveHook = char(__cdecl*)(void*, void*, void*, int); #endif inline FnValveHook ValveHook; #ifdef _WIN64 // void __fastcall ValveUnhook(unsigned __int64 FnAddr, char a2) using FnValveUnhook = void(__fastcall*)(void*, char); #else // void __cdecl ValveUnhook(unsigned int FnAddr, char a2) inline using FnValveUnhook = void(__cdecl*)(unsigned int, char); #endif inline FnValveUnhook ValveUnhook; // Store all hooks inline std::vector EnabledHooks; inline bool Initialize() { #ifdef _WIN64 const HMODULE GameOverlayRenderer = GetModuleHandleA("gameoverlayrenderer64.dll"); #else const HMODULE GameOverlayRenderer = GetModuleHandleA("gameoverlayrenderer.dll"); #endif [[unlikely]] if (!GameOverlayRenderer) return false; #ifdef _WIN64 ValveHook = reinterpret_cast(PatternScan(GameOverlayRenderer, "48 89 5C 24 ? 57 48 83 EC 30 33 C0")); #else ValveHook = reinterpret_cast(PatternScan(GameOverlayRenderer, "55 8B EC 51 8B 45 10 C7")); #endif [[unlikely]] if (!ValveHook) return false; #ifdef _WIN64 const std::uint8_t* JmpAddress = PatternScan(GameOverlayRenderer, "E8 ? ? ? ? FF 15 ? ? ? ? 48 89 45 E8"); #else const std::uint8_t* JmpAddress = PatternScan(GameOverlayRenderer, "E8 ? ? ? ? 83 C4 08 FF 15 ? ? ? ?"); #endif ValveUnhook = reinterpret_cast(const_cast(JmpAddress + 5 + *(DWORD*)(JmpAddress + 1))); [[unlikely]] if (!ValveUnhook) return false; return true; } inline bool Hook(void* FunctionAddress, void* HookAddress, void* OriginalAddress) { const bool SuccessfullyHooked = static_cast(ValveHook(FunctionAddress, HookAddress, OriginalAddress, 0)); [[likely]] if (SuccessfullyHooked) EnabledHooks.push_back(FunctionAddress); return SuccessfullyHooked; } inline void Unhook(void* FunctionAddress) { #ifdef _WIN64 ValveUnhook(FunctionAddress, 0); #else ValveUnhook(reinterpret_cast(FunctionAddress), 0); #endif } inline void UnhookAll() { for (void* EnabledHook : EnabledHooks) Unhook(EnabledHook); } }