diff options
Diffstat (limited to 'src/cs2/iface.h')
| -rw-r--r-- | src/cs2/iface.h | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/cs2/iface.h b/src/cs2/iface.h new file mode 100644 index 0000000..6c3b34b --- /dev/null +++ b/src/cs2/iface.h @@ -0,0 +1,106 @@ +#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<U64>( 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; +} + +inline U64 iface_get_createinterface( PROCESS64* p, U64 module ) { + VECTOR<MODULE_EXPORT64> 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_ENTRY> iface_dump_module( PROCESS64* p, MODULE_ENTRY module ) { + VECTOR<IFACE_ENTRY> 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 ); + entry.ptr = reg.create_fn; + 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_ENTRY> iface_get_all( PROCESS64* p ) { + VECTOR<IFACE_ENTRY> entries; + + VECTOR<MODULE_ENTRY> modules = p->dump_modules(); + for( auto& it : modules ) { + VECTOR<IFACE_ENTRY> module_entries = iface_dump_module( p, it ); + entries.insert( entries.end(), module_entries.begin(), module_entries.end() ); + } + + return entries; +} + |
