From 7ccb819f867493f8ec202ea3b39c94c198c64584 Mon Sep 17 00:00:00 2001 From: JustSomePwner Date: Thu, 30 Aug 2018 14:01:54 +0200 Subject: first --- tf2/vmt.h | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 tf2/vmt.h (limited to 'tf2/vmt.h') diff --git a/tf2/vmt.h b/tf2/vmt.h new file mode 100644 index 0000000..f2a39ac --- /dev/null +++ b/tf2/vmt.h @@ -0,0 +1,79 @@ +#pragma once +#include +#include "util.hpp" + +// todo - dex; rewrite this, VirtualQuery (except for custom codeptr / readptr) and VirtualProtect shouldnt be used +// and we need to copy rtti over too or stuff will break later on + +// correct me if im wrong, but the vtable isnt replaced, instead the original is edited during hooking, rtti should be intact and accessable by game +// class could definetly do with a rewrite tho! + +// ^ you're corrct, but changing page rights and replacing ptrs direclty in rdata (or usually the heap, since thats where vmts go) is not a safe solution +// copying table + aligning it to compensate for rtti is safer +// vac loves scanning memory regions but it doesnt really do much outside of game servers (only loads some shit for checking DEP and stuff) + +// trash + +//llama is a fucking nigger +//true + +namespace hooks +{ + class c_vmt { + uintptr_t* m_table; + uintptr_t* m_original; + std::vector< uintptr_t > m_new; + public: + int count( ) { + int vfunc_count{ }; + + while( m_original[ vfunc_count ] ) { + vfunc_count++; + }; + + return vfunc_count; + } + + c_vmt( void* table ) { + if( !table ) { + return; + } + + this->m_table = reinterpret_cast< uintptr_t* >( table ); + this->m_original = *reinterpret_cast< uintptr_t** >( this->m_table ); + + for( int i = -1; i < this->count( ); ++i ) { + this->m_new.push_back( this->m_original[ i ] ); + } + + auto data = this->m_new.data( ); + *this->m_table = uintptr_t( &data[ 1 ] ); + } + + ~c_vmt( ) { } + + template< typename T = uintptr_t > T get_function( int index ) { + return( ( T )( this->m_new.at( index + 1 ) ) ); + } + + template< typename T = uintptr_t > T get_old_function( int index ) { + return( ( T )( this->m_original[ index ] ) ); + } + + void hook( int index, uintptr_t new_func ) { + this->m_new.at( index + 1 ) = new_func; + } + + void unhook( int index ) { + this->m_new.at( index + 1 ) = this->m_original[ index ]; + } + + void hook( int index, void* new_func ) { + hook( index, reinterpret_cast< uintptr_t >( new_func ) ); + } + + void restore( ) const { + *this->m_table = uintptr_t( m_original ); + } + }; +} \ No newline at end of file -- cgit v1.2.3