From 1b43cae68ecf44022c94e0522710b0932e0d20a7 Mon Sep 17 00:00:00 2001 From: aixxe Date: Mon, 19 Dec 2016 21:10:10 +0000 Subject: [PATCH] Add virtual method table hooking class. * github.com/aixxe/vmthook (8f0479b) Signed-off-by: aixxe --- include/vmthook/vmthook.h | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 include/vmthook/vmthook.h diff --git a/include/vmthook/vmthook.h b/include/vmthook/vmthook.h new file mode 100644 index 0000000..2ee1a32 --- /dev/null +++ b/include/vmthook/vmthook.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include +#include + +class VMTHook { + private: + std::uintptr_t** baseclass = nullptr; + std::unique_ptr current_vft = nullptr; + std::uintptr_t* original_vft = nullptr; + std::size_t total_functions = 0; + public: + VMTHook(void) = default; + + VMTHook(void* baseclass) { + this->baseclass = static_cast(baseclass); + + while (static_cast(*this->baseclass)[this->total_functions]) + ++this->total_functions; + + const std::size_t table_size = this->total_functions * sizeof(std::uintptr_t); + + this->original_vft = *this->baseclass; + this->current_vft = std::make_unique(this->total_functions); + + std::memcpy(this->current_vft.get(), this->original_vft, table_size); + + *this->baseclass = this->current_vft.get(); + }; + + ~VMTHook() { + *this->baseclass = this->original_vft; + }; + + inline void* GetOriginalFunction(std::size_t function_index) { + return reinterpret_cast(this->original_vft[function_index]); + } + + template inline const Function GetOriginalFunction(std::size_t function_index) { + return reinterpret_cast(this->original_vft[function_index]); + } + + inline bool HookFunction(void* new_function, const std::size_t function_index) { + if (function_index > this->total_functions) + return false; + + this->current_vft[function_index] = reinterpret_cast(new_function); + + return true; + } + + inline bool UnhookFunction(const std::size_t function_index) { + if (function_index > this->total_functions) + return false; + + this->current_vft[function_index] = this->original_vft[function_index]; + + return true; + } + + inline std::size_t GetTotalFunctions() { + return this->total_functions; + } +}; \ No newline at end of file