From 7868f363128373048c429dfbe39492db9b2ca8a8 Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Mon, 17 May 2021 22:40:32 +0200 Subject: [PATCH] Support getting v-table entries --- src/common/utils/hook.hpp | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/common/utils/hook.hpp b/src/common/utils/hook.hpp index 251131e..bb24f8c 100644 --- a/src/common/utils/hook.hpp +++ b/src/common/utils/hook.hpp @@ -8,6 +8,55 @@ using namespace asmjit::x86; namespace utils::hook { + namespace detail + { + template + std::vector get_iota_functions() + { + if constexpr (entries == 0) + { + std::vector functions; + return functions; + } + else + { + auto functions = get_iota_functions(); + functions.emplace_back([]() + { + return entries - 1; + }); + return functions; + } + } + } + + // Gets the pointer to the entry in the v-table. + // It seems otherwise impossible to get this. + // This is ugly as fuck and only safely works on x64 + // Example: + // ID3D11Device* device = ... + // auto entry = get_vtable_entry(device, &ID3D11Device::CreateTexture2D); + template + void** get_vtable_entry(Class* obj, T (Class::* entry)(Args ...)) + { + union + { + decltype(entry) func; + void* pointer; + }; + + func = entry; + + auto iota_functions = detail::get_iota_functions(); + auto* object = iota_functions.data(); + + using FakeFunc = size_t(__thiscall*)(void* self); + auto index = static_cast(pointer)(&object); + + void** obj_v_table = *reinterpret_cast(obj); + return &obj_v_table[index]; + } + class assembler : public Assembler { public: