3 #include <plugify/mem_protector.hpp>
17 template<
typename F> requires(std::is_pointer_v<F> && std::is_function_v<std::remove_pointer_t<F>>)
18 F HookMethod(
void* vtp, F func,
int offset) {
19 const uintptr_t vtable = *
reinterpret_cast<uintptr_t*
>(vtp);
20 const uintptr_t entry = vtable + (
static_cast<size_t>(offset) *
sizeof(
void*));
21 const uintptr_t orig = *
reinterpret_cast<uintptr_t*
>(entry);
22 MemProtector memProtector(entry,
sizeof(entry), ProtFlag::RWX);
23 *
reinterpret_cast<uintptr_t*
>(entry) =
reinterpret_cast<uintptr_t
>(func);
24 return reinterpret_cast<F
>(orig);
39 int GetVirtualTableIndex(F func, ProtFlag flag = ProtFlag::RWX) {
40 void* ptr = (
void*&)func;
42 constexpr
size_t size = 12;
44 MemProtector protector(ptr, size, flag);
46 #if defined(__GNUC__) || defined(__clang__)
47 struct GCC_MemFunPtr {
56 auto mfp_detail = (GCC_MemFunPtr*)&ptr;
57 if (mfp_detail->vti_plus1 & 1) {
58 vtindex = (mfp_detail->vti_plus1 - 1) /
sizeof(
void*);
64 #elif defined(_MSC_VER)
92 auto finder = [&](uint8_t* addr) {
93 std::unique_ptr<MemProtector> protector;
98 addr += 5 + *(uint32_t*)(addr + 1);
100 protector = std::make_unique<MemProtector>(addr, size, flag);
104 #if INTPTR_MAX == INT64_MAX
105 if (addr[0] == 0x48 && addr[1] == 0x8B && addr[2] == 0x01) {
110 if (addr[0] == 0x8B && addr[1] == 0x01) {
113 }
else if (addr[0] == 0x8B && addr[1] == 0x44 && addr[2] == 0x24 && addr[3] == 0x04 && addr[4] == 0x8B && addr[5] == 0x00) {
121 constexpr
int PtrSize =
static_cast<int>(
sizeof(
void*));
123 if (*addr++ == 0xFF) {
125 return *++addr / PtrSize;
126 else if (*addr == 0xA0)
127 return int(*((uint32_t*)++addr)) / PtrSize;
128 else if (*addr == 0x20)
137 return finder((uint8_t*)ptr);
139 #error "Compiler not support"