6#ifndef SAFETYHOOK_USE_CXXMODULES
9#include <unordered_map>
15#include "safetyhook/common.hpp"
16#include "safetyhook/utility.hpp"
20class SAFETYHOOK_API VmHook final {
23 VmHook(
const VmHook&) =
delete;
24 VmHook(VmHook&& other)
noexcept;
25 VmHook& operator=(
const VmHook&) =
delete;
26 VmHook& operator=(VmHook&& other)
noexcept;
33 template <
typename T> [[nodiscard]] T
original()
const {
return reinterpret_cast<T
>(m_original_vm); }
41 template <
typename RetT = void,
typename... Args> RetT
call(Args... args) {
42 return original<RetT (*)(Args...)>()(args...);
50 template <
typename RetT = void,
typename... Args> RetT
ccall(Args... args) {
51 return original<RetT(SAFETYHOOK_CCALL*)(Args...)>()(args...);
59 template <
typename RetT = void,
typename... Args> RetT
thiscall(Args... args) {
60 return original<RetT(SAFETYHOOK_THISCALL*)(Args...)>()(args...);
68 template <
typename RetT = void,
typename... Args> RetT
stdcall(Args... args) {
69 return original<RetT(SAFETYHOOK_STDCALL*)(Args...)>()(args...);
77 template <
typename RetT = void,
typename... Args> RetT
fastcall(Args... args) {
78 return original<RetT(SAFETYHOOK_FASTCALL*)(Args...)>()(args...);
84 uint8_t* m_original_vm{};
86 uint8_t** m_vmt_entry{};
89 std::shared_ptr<Allocation> m_new_vmt_allocation{};
95class SAFETYHOOK_API VmtHook final {
115 error.allocator_error = err;
123 [[nodiscard]]
static std::expected<VmtHook, Error>
create(
void*
object);
126 VmtHook(
const VmtHook&) =
delete;
127 VmtHook(VmtHook&& other)
noexcept;
128 VmtHook& operator=(
const VmtHook&) =
delete;
129 VmtHook& operator=(VmtHook&& other)
noexcept;
147 template <
typename T> [[nodiscard]] std::expected<VmHook, Error>
hook_method(
size_t index, T new_function) {
151 hook.m_original_vm = m_new_vmt[index];
152 store(
reinterpret_cast<uint8_t*
>(&hook.m_new_vm), new_function);
153 hook.m_vmt_entry = &m_new_vmt[index];
154 hook.m_new_vmt_allocation = m_new_vmt_allocation;
155 m_new_vmt[index] = hook.m_new_vm;
162 std::unordered_map<void*, uint8_t**> m_objects{};
165 std::shared_ptr<Allocation> m_new_vmt_allocation{};
166 uint8_t** m_new_vmt{};
Allocator for allocating memory near target addresses.
Error
The error type returned by the allocate functions.
Definition allocator.hpp:80
A hook class that allows for hooking a single method in a VMT.
Definition vmt_hook.hpp:20
RetT fastcall(Args... args)
Calls the original method with the __fastcall calling convention.
Definition vmt_hook.hpp:77
RetT stdcall(Args... args)
Calls the original method with the __stdcall calling convention.
Definition vmt_hook.hpp:68
T original() const
Gets the original method pointer.
Definition vmt_hook.hpp:33
RetT ccall(Args... args)
Calls the original method with the __cdecl calling convention.
Definition vmt_hook.hpp:50
RetT thiscall(Args... args)
Calls the original method with the __thiscall calling convention.
Definition vmt_hook.hpp:59
void reset()
Removes the hook.
RetT call(Args... args)
Calls the original method.
Definition vmt_hook.hpp:41
A hook class that copies an entire VMT for a given object and replaces it.
Definition vmt_hook.hpp:95
static std::expected< VmtHook, Error > create(void *object)
Creates a new VmtHook object. Will clone the VMT of the given object and replace it.
void reset()
Removes the hook from all objects.
void remove(void *object)
Removes the hook.
void apply(void *object)
Applies the hook.
std::expected< VmHook, Error > hook_method(size_t index, T new_function)
Hooks a method in the VMT.
Definition vmt_hook.hpp:147
Error type for VmtHook.
Definition vmt_hook.hpp:98
Allocator::Error allocator_error
Allocator error information.
Definition vmt_hook.hpp:106
static Error bad_allocation(Allocator::Error err)
Create a BAD_ALLOCATION error.
Definition vmt_hook.hpp:112
enum safetyhook::VmtHook::Error::@040335202272131273375301110052022100240240047176 type
The type of error.
@ BAD_ALLOCATION
An error occurred while allocating memory.
Definition vmt_hook.hpp:101