Add virtual method table hooking class.
* github.com/aixxe/vmthook (8f0479b) Signed-off-by: aixxe <me@aixxe.net>
This commit is contained in:
parent
da0e8efd27
commit
1b43cae68e
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue