Add required hooking extensions
This commit is contained in:
parent
0dabe137cb
commit
feb1282e03
@ -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");
|
||||
@ -245,8 +249,16 @@ namespace utils::hook
|
||||
|
||||
if (use_far)
|
||||
{
|
||||
copy(patch_pointer, jump_data, sizeof(jump_data));
|
||||
copy(patch_pointer + 2, &data, sizeof(data));
|
||||
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
|
||||
{
|
||||
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user