1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#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;
return addr;
}
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 );
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_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;
}
inline void iface_dump_to_file( PROCESS64* p ) {
VECTOR<IFACE_ENTRY> 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" );
}
|