-
Notifications
You must be signed in to change notification settings - Fork 0
/
__init__.py
81 lines (57 loc) · 1.71 KB
/
__init__.py
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
from binaryninja import *
def get_xfg_hashes(bv):
IMAGE_GUARD_FLAG_FID_XFG = 8
xfg_hashes = {}
sym = bv.get_symbol_by_raw_name('__gfids_table')
if not sym:
return
var = bv.get_data_var_at(sym.address)
if not var:
return
for func_table in var.value:
if not isinstance(func_table, dict):
continue
addr = func_table['rvAddr'] + bv.start
if not (func_table['metadata'] & IMAGE_GUARD_FLAG_FID_XFG):
continue
try:
xfg_hash = bv.read_int(addr - 8, 8) & 0xffffffffffffffff
except:
continue
if xfg_hash in xfg_hashes:
xfg_hashes[xfg_hash].append(addr)
else:
xfg_hashes[xfg_hash] = [addr]
return xfg_hashes
def get_xfg_pointer(bv):
sym = bv.get_symbol_by_raw_name('__load_configuration_directory_table')
if not sym:
return
var = bv.get_data_var_at(sym.address)
if not var:
return
if var.value['guardFlags'] == 0:
return
xfg_pointer = var.value['guardXFGDispatchFunctionPointer']
return xfg_pointer
def add_xfg_xref(bv):
if bv.view_type != 'PE':
log_warn('xfg only works with PE files')
return
xfg_pointer = get_xfg_pointer(bv)
# log_warn('xfg_pointer: 0x%x' % xfg_pointer)
xfg_hashes = get_xfg_hashes(bv)
# log_warn('xfg_hashes: %s' % xfg_hashes)
bv.begin_undo_actions()
for ref in bv.get_code_refs(xfg_pointer):
value = ref.function.get_reg_value_at(ref.address, 'r10')
if value.type != RegisterValueType.ConstantValue:
continue
val = value.value & 0xffffffffffffffff | 1
if val not in xfg_hashes:
continue
for addr in xfg_hashes[val]:
log_warn('adding xref: 0x%x ==> 0x%x' % (ref.address, addr))
ref.function.add_user_code_ref(ref.address, addr)
bv.commit_undo_actions()
PluginCommand.register("Add XFG Xref", "Add XFG Xref", add_xfg_xref)