154 lines
4.5 KiB
C++
154 lines
4.5 KiB
C++
#pragma once
|
|
#include <Windows.h>
|
|
#include <cstddef>
|
|
#include <vector>
|
|
|
|
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<int>{};
|
|
char* StartPos = const_cast<char*>(Pattern);
|
|
char* EndPos = const_cast<char*>(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<IMAGE_DOS_HEADER*>(Module);
|
|
const IMAGE_NT_HEADERS* NtHeaders = reinterpret_cast<IMAGE_NT_HEADERS*>(reinterpret_cast<std::uint8_t*>(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<std::uint8_t*>(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<void*> 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<FnValveHook>(PatternScan(GameOverlayRenderer, "48 89 5C 24 ? 57 48 83 EC 30 33 C0"));
|
|
#else
|
|
ValveHook = reinterpret_cast<FnValveHook>(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<FnValveUnhook>(const_cast<std::uint8_t*>(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<bool>(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<unsigned int>(FunctionAddress), 0);
|
|
#endif
|
|
}
|
|
|
|
inline void UnhookAll()
|
|
{
|
|
for (void* EnabledHook : EnabledHooks)
|
|
Unhook(EnabledHook);
|
|
}
|
|
}
|