Add required hooking extensions

This commit is contained in:
momo5502 2022-05-23 17:57:29 +02:00
parent 0dabe137cb
commit feb1282e03
2 changed files with 58 additions and 18 deletions

View File

@ -230,12 +230,16 @@ namespace utils::hook
return call(pointer, reinterpret_cast<void*>(data));
}
void jump(void* pointer, void* data, const bool use_far)
void jump(void* pointer, void* data, const bool use_far, const bool use_safe)
{
static const unsigned char jump_data[] = {
0x48, 0xb8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0xff, 0xe0
};
static const unsigned char jump_data_safe[] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00
};
if (!use_far && is_relatively_far(pointer, data))
{
throw std::runtime_error("Too far away to create 32bit relative branch");
@ -244,10 +248,18 @@ namespace utils::hook
auto* patch_pointer = PBYTE(pointer);
if (use_far)
{
if (use_safe)
{
copy(patch_pointer, jump_data_safe, sizeof(jump_data_safe));
copy(patch_pointer + sizeof(jump_data_safe), &data, sizeof(data));
}
else
{
copy(patch_pointer, jump_data, sizeof(jump_data));
copy(patch_pointer + 2, &data, sizeof(data));
}
}
else
{
set<uint8_t>(patch_pointer, 0xE9);
@ -255,14 +267,14 @@ namespace utils::hook
}
}
void jump(const size_t pointer, void* data, const bool use_far)
void jump(const size_t pointer, void* data, const bool use_far, const bool use_safe)
{
return jump(reinterpret_cast<void*>(pointer), data, use_far);
return jump(reinterpret_cast<void*>(pointer), data, use_far, use_safe);
}
void jump(const size_t pointer, const size_t data, const bool use_far)
void jump(const size_t pointer, const size_t data, const bool use_far, const bool use_safe)
{
return jump(pointer, reinterpret_cast<void*>(data), use_far);
return jump(pointer, reinterpret_cast<void*>(data), use_far, use_safe);
}
void* assemble(const std::function<void(assembler&)>& asm_function)
@ -297,6 +309,31 @@ namespace utils::hook
return inject(reinterpret_cast<void*>(pointer), data);
}
void move_hook(void* pointer)
{
auto* data_ptr = static_cast<uint8_t*>(pointer);
if (data_ptr[0] == 0xE9)
{
auto* target = follow_branch(data_ptr);
nop(data_ptr, 1);
jump(data_ptr + 1, target);
}
else if (data_ptr[0] == 0xFF && data_ptr[1] == 0x25)
{
copy(data_ptr + 1, data_ptr, 0x14);
nop(data_ptr, 1);
}
else
{
throw std::runtime_error("No branch instruction found");
}
}
void move_hook(const size_t pointer)
{
return move_hook(reinterpret_cast<void*>(pointer));
}
void* follow_branch(void* address)
{
auto* const data = static_cast<uint8_t*>(address);

View File

@ -10,20 +10,20 @@ namespace utils::hook
{
namespace detail
{
template<size_t entries>
template <size_t Entries>
std::vector<size_t(*)()> get_iota_functions()
{
if constexpr (entries == 0)
if constexpr (Entries == 0)
{
std::vector<size_t(*)()> functions;
return functions;
}
else
{
auto functions = get_iota_functions<entries - 1>();
auto functions = get_iota_functions<Entries - 1>();
functions.emplace_back([]()
{
return entries - 1;
return Entries - 1;
});
return functions;
}
@ -36,7 +36,7 @@ namespace utils::hook
// Example:
// ID3D11Device* device = ...
// auto entry = get_vtable_entry(device, &ID3D11Device::CreateTexture2D);
template <size_t entries = 100, typename Class, typename T, typename... Args>
template <size_t Entries = 100, typename Class, typename T, typename... Args>
void** get_vtable_entry(Class* obj, T (Class::* entry)(Args ...))
{
union
@ -47,11 +47,11 @@ namespace utils::hook
func = entry;
auto iota_functions = detail::get_iota_functions<entries>();
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);
using fake_func = size_t(__thiscall*)(void* self);
auto index = static_cast<fake_func>(pointer)(&object);
void** obj_v_table = *reinterpret_cast<void***>(obj);
return &obj_v_table[index];
@ -154,15 +154,18 @@ namespace utils::hook
void call(size_t pointer, void* data);
void call(size_t pointer, size_t data);
void jump(void* pointer, void* data, bool use_far = false);
void jump(size_t pointer, void* data, bool use_far = false);
void jump(size_t pointer, size_t data, bool use_far = false);
void jump(void* pointer, void* data, bool use_far = false, bool use_safe = false);
void jump(size_t pointer, void* data, bool use_far = false, bool use_safe = false);
void jump(size_t pointer, size_t data, bool use_far = false, bool use_safe = false);
void* assemble(const std::function<void(assembler&)>& asm_function);
void inject(void* pointer, const void* data);
void inject(size_t pointer, const void* data);
void move_hook(void* pointer);
void move_hook(size_t pointer);
template <typename T>
T extract(void* address)
{