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
|
#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;
}
|