Support getting v-table entries

This commit is contained in:
Maurice Heumann 2021-05-17 22:40:32 +02:00
parent 949258ae13
commit 7868f36312

View File

@ -8,6 +8,55 @@ using namespace asmjit::x86;
namespace utils::hook
{
namespace detail
{
template<size_t entries>
std::vector<size_t(*)()> get_iota_functions()
{
if constexpr (entries == 0)
{
std::vector<size_t(*)()> functions;
return functions;
}
else
{
auto functions = get_iota_functions<entries - 1>();
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 <size_t entries = 100, typename Class, typename T, typename... Args>
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<entries>();
auto* object = iota_functions.data();
using FakeFunc = size_t(__thiscall*)(void* self);
auto index = static_cast<FakeFunc>(pointer)(&object);
void** obj_v_table = *reinterpret_cast<void***>(obj);
return &obj_v_table[index];
}
class assembler : public Assembler
{
public: