summaryrefslogtreecommitdiff
path: root/src/cs2/iface.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cs2/iface.h')
-rw-r--r--src/cs2/iface.h106
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, &reg, 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, &reg, 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;
+}
+