summaryrefslogtreecommitdiff
path: root/loader/iface.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'loader/iface.hpp')
-rw-r--r--loader/iface.hpp198
1 files changed, 198 insertions, 0 deletions
diff --git a/loader/iface.hpp b/loader/iface.hpp
new file mode 100644
index 0000000..49a4dc5
--- /dev/null
+++ b/loader/iface.hpp
@@ -0,0 +1,198 @@
+#pragma once
+#include <vector>
+#include <TlHelp32.h>
+#include "winapi.hpp"
+#include "util.hpp"
+
+namespace iface
+{
+ class container {
+ private:
+ struct reg {
+ char m_key;
+ uintptr_t m_ptr;
+ uintptr_t m_module;
+ char m_module_name[ 64 ];
+ char m_name[ 64 ];
+ };
+
+ std::vector< reg > m_regs;
+ public:
+ void emplace_reg( uintptr_t ptr, uintptr_t module_, const char* name, const char* module_name, char name_key ) {
+ reg new_reg{ };
+ new_reg.m_ptr = ptr;
+ new_reg.m_module = module_;
+
+ memcpy( new_reg.m_name, name, 64 );
+ memcpy( new_reg.m_module_name, module_name, 64 );
+
+ new_reg.m_key = name_key;
+
+ m_regs.emplace_back( new_reg );
+ }
+
+ auto& get_regs( ) {
+ return m_regs;
+ }
+ };
+
+ struct iface_reg_t {
+ void* m_create_fn;
+ const char* m_name;
+ uintptr_t m_next;
+
+ inline auto follow( HANDLE process ) {
+ iface_reg_t buf;
+ ReadProcessMemory( process, ( void* )( m_next ), &buf, sizeof( buf ), nullptr );
+ return buf;
+ }
+ };
+
+ class manager {
+ HANDLE& m_process;
+ container m_container;
+
+ inline auto is_createinterface_export( uintptr_t export_ ) {
+ uint8_t buf[ 12 ];
+
+ ReadProcessMemory( m_process, ( void* )( export_ ), buf, sizeof( buf ), nullptr );
+
+ return( buf[ 0 ] == 0x55
+ && buf[ 4 ] == 0xe9
+ && buf[ 9 ] == 0xcc
+ && buf[ 10 ] == 0xcc );
+ }
+
+ inline auto is_createinterface_fn( uintptr_t fn_ ) {
+ uint8_t buf[ 12 ];
+
+ ReadProcessMemory( m_process, ( void* )( fn_ ), buf, sizeof( buf ), nullptr );
+
+ return( buf[ 0 ] == 0x55
+ && buf[ 4 ] == 0x8b
+ && buf[ 10 ] == 0x57 );
+ }
+
+ inline auto follow_createinterface_export( uintptr_t export_ ) {
+ uintptr_t jmp = export_ + 0x4;
+
+ uintptr_t rel;
+ ReadProcessMemory( m_process, ( void* )( jmp + 0x1 ), &rel, sizeof( rel ), nullptr );
+
+ return jmp + rel + 0x5;
+ }
+
+ inline auto find_list_ptr( uintptr_t createinterface ) {
+ uintptr_t
+ first = createinterface + 0x6,
+ second,
+ third;
+
+ ReadProcessMemory( m_process, ( void* )( first ), &second, sizeof( second ), nullptr );
+ ReadProcessMemory( m_process, ( void* )( second ), &third, sizeof( third ), nullptr );
+
+ return third;
+ }
+
+ inline auto get_list( uintptr_t ptr ) {
+ iface_reg_t reg;
+ ReadProcessMemory( m_process, ( void* )( ptr ), &reg, sizeof( reg ), nullptr );
+
+ return reg;
+ }
+
+ public:
+ manager( HANDLE& process ) : m_process( process ) { };
+
+ inline void dump_from_module( HMODULE mod, const char* module_name ) {
+ auto read_str = [ this ]( char* buf, size_t size, uintptr_t addr ) {
+ for( size_t i{ }; i < size; ++i ) {
+ char _c;
+ ReadProcessMemory( m_process, ( void* )( addr + i ), &_c, 1, 0 );
+ buf[ i ] = _c;
+ if( !_c ) break;
+ }
+
+ buf[ size - 1 ] = 0;
+ };
+
+ auto enc_str = [ ]( char* buf, size_t size, char key ) {
+ for( size_t i{ }; i < size; ++i ) {
+ buf[ i ] ^= key;
+ }
+ };
+
+ auto create_interface = winapi::get_procaddr_ex( m_process, mod, xors( "CreateInterface" ) );
+ if( !create_interface || !is_createinterface_export( create_interface ) )
+ return;
+
+ auto fn = follow_createinterface_export( create_interface );
+ if( !is_createinterface_fn( fn ) )
+ return;
+
+ auto list_ptr = find_list_ptr( fn );
+ auto list = get_list( list_ptr );
+
+ char name_buf[ 64 ];
+ char module_buf[ 64 ];
+
+ do {
+ read_str( name_buf, 64, ( uintptr_t )( list.m_name ) );
+ strcpy( module_buf, module_name );
+
+ srand( list_ptr );
+ auto key = rand( ) & 0xff;
+
+ enc_str( name_buf, 64, key );
+ enc_str( module_buf, 64, key );
+
+ uintptr_t iface_ptr = 0;
+ ReadProcessMemory( m_process, ( void* )( ( uintptr_t )list.m_create_fn + 1 ),
+ &iface_ptr, sizeof( uintptr_t ), nullptr );
+
+ m_container.emplace_reg( iface_ptr, uintptr_t( mod ), name_buf, module_name, key );
+
+ list_ptr = list.m_next;
+ list = get_list( list_ptr );
+ } while( list_ptr && name_buf[ 0 ] && list_ptr != list.m_next );
+ }
+
+ void dump_all_modules( int pid ) {
+ HANDLE t32_snapshot;
+ MODULEENTRY32 entry;
+
+ t32_snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
+ entry.dwSize = sizeof( MODULEENTRY32 );
+
+ for( Module32First( t32_snapshot, &entry );
+ !!Module32Next( t32_snapshot, &entry ); ) {
+
+ //why valve troll me
+ if( strstr( entry.szModule, xors( "valve_avi" ) ) )
+ continue;
+
+ dump_from_module( ( HMODULE )( entry.modBaseAddr ), entry.szModule );
+ }
+ }
+
+ auto count( ) {
+ return m_container.get_regs( ).size( );
+ }
+
+ auto& get( ) {
+ return m_container;
+ }
+
+ uintptr_t write_to_process( ) {
+ size_t count_ = count( );
+ size_t size = count_ * 137 + sizeof( size_t );
+
+ auto allocation = VirtualAllocEx( m_process, 0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
+ WriteProcessMemory( m_process, allocation, &count_, sizeof( count_ ), nullptr );
+ WriteProcessMemory( m_process, ( void* )( uintptr_t( allocation ) + 0x4 ),
+ get( ).get_regs( ).data( ), size, nullptr );
+
+ return ( uintptr_t )( allocation );
+ }
+ };
+} \ No newline at end of file