Add virtual method table hooking class.

* github.com/aixxe/vmthook (8f0479b)

Signed-off-by: aixxe <me@aixxe.net>
This commit is contained in:
aixxe 2016-12-19 21:10:10 +00:00
parent da0e8efd27
commit 1b43cae68e
1 changed files with 66 additions and 0 deletions

66
include/vmthook/vmthook.h Normal file
View File

@ -0,0 +1,66 @@
#pragma once
#include <cstdint>
#include <cstddef>
#include <cstring>
#include <memory>
class VMTHook {
private:
std::uintptr_t** baseclass = nullptr;
std::unique_ptr<std::uintptr_t[]> 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<std::uintptr_t**>(baseclass);
while (static_cast<std::uintptr_t*>(*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<std::uintptr_t[]>(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<void*>(this->original_vft[function_index]);
}
template <typename Function> inline const Function GetOriginalFunction(std::size_t function_index) {
return reinterpret_cast<Function>(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<std::uintptr_t>(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;
}
};