From 3d412a4b30a9f7c7f51ea6562e694315948bd3da Mon Sep 17 00:00:00 2001 From: boris Date: Wed, 28 Nov 2018 16:00:02 +1300 Subject: cleaned up in short, the cheat and loader are now separate solutions. unused stuff was moved into the legacy solution in case anyone wants to compile it or whatever. i can change this back if you want to. also, i configured the loader to compile in x64, and have separate build types for linux and win64 --- legacy/loader/iface.hpp | 198 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 legacy/loader/iface.hpp (limited to 'legacy/loader/iface.hpp') diff --git a/legacy/loader/iface.hpp b/legacy/loader/iface.hpp new file mode 100644 index 0000000..49a4dc5 --- /dev/null +++ b/legacy/loader/iface.hpp @@ -0,0 +1,198 @@ +#pragma once +#include +#include +#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 ), ®, 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 -- cgit v1.2.3