#pragma once #include #include #include #include #include #include #include #if defined(HOOK_HLTV) || defined(HOOK_FILESYSTEM) #define private public #define protected public template class MethodThunk { public: void Constructor(TArgs ... args) { new(this) T(args ...); } void Destructor() { (*(T *)this).~T(); } }; namespace MsvcMethod { namespace Detail { using Counter = std::size_t(*)(); template std::size_t GetIndex() { return N; } template constexpr auto GenerateCounters_Helper(std::index_sequence) { // There is no make_array (and/or deduction guides), so we need to explicitly define array template params return std::array { &GetIndex ... }; } template auto counters = GenerateCounters_Helper(std::make_index_sequence{}); struct VIndexGetter {}; struct ThisGetter { decltype(auto) GetThis() const { return this; } decltype(auto) GetThis(...) const { return this; } }; template class Singleton { public: static T &GetInstance() { static T instance = {}; return instance; } }; // primary template template struct is_variadic_function : std::false_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template struct is_variadic_function : std::true_type {}; template constexpr bool is_variadic_function_v = is_variadic_function::value; template constexpr bool is_function_v = std::is_function::value; } // namespace Detail static constexpr auto& counters = Detail::counters<256>; template std::enable_if_t, std::uintptr_t> GetVirtualIndex(TMethod T::*method) { decltype(auto) pcounters = counters.data(); decltype(auto) vIndexGetter = (Detail::VIndexGetter *)&pcounters; using VIndexGetterFunction = std::conditional_t, std::size_t (Detail::VIndexGetter::*)(...) const, std::size_t(Detail::VIndexGetter::*)() const>; VIndexGetterFunction vIndexGetterFunction; { *(std::uintptr_t *)&vIndexGetterFunction = *(std::uintptr_t *)&method; } return (vIndexGetter->*vIndexGetterFunction)(); } template TMethod &declmethod(TMethod T::*method); template std::enable_if_t, std::uintptr_t> GetVirtualAddress(TMethod T::*method) { using ThisGetterFunction = std::conditional_t, const T *(T::*)(...) const, const T *(T::*)() const>; ThisGetterFunction thisGetterFunction = *(ThisGetterFunction *)&method; { decltype(auto) m = static_cast, const Detail::ThisGetter *(Detail::ThisGetter::*)(...) const, const Detail::ThisGetter *(Detail::ThisGetter::*)() const>>(&Detail::ThisGetter::GetThis); *(std::uintptr_t *)&thisGetterFunction = *(std::uintptr_t *)&m; } return *(*(std::uintptr_t **)(Detail::Singleton::GetInstance().*thisGetterFunction)() + GetVirtualIndex(method)); } template std::enable_if_t, std::uintptr_t> GetAddress(TMethod (T::*method)) { return (std::uintptr_t &)method; } template std::enable_if_t, std::uintptr_t> GetAddress(TMethod (*method)) { return (std::uintptr_t &)method; } } // namespace MsvcMethod #ifdef _MSC_VER #define GLOBALVAR_LINK(offset, symbol, var, ...) { offset, #symbol, (size_t)&##var, __VA_ARGS__ } #define HOOK_SYMBOLDEF(offset, symbol, func, ...) { offset, #symbol, MsvcMethod::GetAddress<__VA_ARGS__>(&func) } #define HOOK_SYMBOL_VIRTUAL_DEF(offset, symbol, func, ...) { offset, #symbol, MsvcMethod::GetVirtualAddress<__VA_ARGS__>(&func) } #define HOOK_SYMBOL_VIRTUAL_EX(offset, class, func, ...) { offset, #class#func, MsvcMethod::GetVirtualAddress(&class::func))>::type, class>(&class::func) } #define HOOK_DEF(offset, func, ...) HOOK_SYMBOLDEF(offset, func, func, __VA_ARGS__) #define HOOK_VIRTUAL_DEF(offset, func, ...) HOOK_SYMBOL_VIRTUAL_DEF(offset, func, func, __VA_ARGS__) #else #error Hooking stuff is only available using MSVC compiler. #endif // _MSC_VER #endif // #if defined(HOOK_HLTV) || defined(HOOK_FILESYSTEM)