66 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #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;
 | |
| 		}
 | |
| }; |