#pragma once #include "../process64.h" struct IFACE_ENTRY { U64 ptr; STR<64> name; U64 module; STR<64> module_name; }; struct IFACE_REG { U64 create_fn; U64 name; U64 next; }; inline bool iface_is_createinterface_export( PROCESS64* p, U64 exp ) { U8 data[64]; p->read( exp, data, 64 ); // mov r9, cs:iface_list // mov r10, rdx return data[0] == 0x4c && data[1] == 0x8b && data[2] == 0x0d && data[7] == 0x4c && data[8] == 0x8b && data[9] == 0xd2; } inline U64 iface_get_list( PROCESS64* p, U64 createiface ) { U8 data[64]; p->read( createiface, data, 64 ); U32 off = *(U32*)&data[3]; U64 list = createiface + off + 7; return p->read( list ); } inline U64 iface_get_address( PROCESS64* p, U64 create_fn ) { U8 data[64]; p->read( create_fn, data, 64 ); U32 off = *(U32*)&data[3]; U64 addr = create_fn + off + 7; return addr; } inline U64 iface_get_createinterface( PROCESS64* p, U64 module ) { VECTOR exports = module_get_exports64( module, p->get_base() ); for( auto& it : exports ) { if( fnv1a( it.name ) == "CreateInterface"fnv ) return it.base; } return {}; } inline VECTOR iface_dump_module( PROCESS64* p, MODULE_ENTRY module ) { VECTOR entries; U64 createiface, list, head, prev; IFACE_REG reg; createiface = iface_get_createinterface( p, module.base ); if( !createiface ) return entries; if( !iface_is_createinterface_export( p, createiface ) ) return entries; list = iface_get_list( p, createiface ); if( !list ) return entries; head = list; prev = 0; p->read( head, ®, sizeof( IFACE_REG ) ); for( ;; ) { IFACE_ENTRY entry; p->read( reg.name, entry.name.data, 64 ); U64 ptr = iface_get_address( p, reg.create_fn ); entry.ptr = ptr; entry.module = module.base; entry.module_name = module.name; entries.push_back( entry ); if( reg.next == head || reg.next == prev || !reg.next ) break; prev = reg.next; p->read( reg.next, ®, sizeof( IFACE_REG ) ); } return entries; } inline VECTOR iface_get_all( PROCESS64* p ) { VECTOR entries; VECTOR modules = p->dump_modules(); for( auto& it : modules ) { VECTOR module_entries = iface_dump_module( p, it ); entries.insert( entries.end(), module_entries.begin(), module_entries.end() ); } return entries; } inline void iface_dump_to_file( PROCESS64* p ) { VECTOR entries = iface_get_all( p ); static STR<9999999> output; memset( output, 0, sizeof( output.data ) ); for( auto& it : entries ) { U64 off = it.ptr - it.module; sprintf( output, "%siface: %s @%s+0x%llx [0x%llx]\n", output.data, it.name.data, it.module_name.data, off, it.ptr ); } u_write_to_file( output.data, "interfaces.txt" ); }