-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathquickScanPe.py
More file actions
137 lines (118 loc) · 4.58 KB
/
quickScanPe.py
File metadata and controls
137 lines (118 loc) · 4.58 KB
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
126
127
128
129
130
131
132
133
134
135
136
137
from capstone import *
def get_function_ranges(pe):
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.skipdata = True
text_section = next(s for s in pe.sections if s.Name.startswith(b'.text'))
code = text_section.get_data()
start_addr = text_section.VirtualAddress
end_addr = start_addr + text_section.Misc_VirtualSize
functions = []
current_func = None
insn_list = list(md.disasm(code, start_addr))
i = 0
while i < len(insn_list):
insn = insn_list[i]
if insn.mnemonic == 'push' and insn.op_str == 'rbp':
# 向上搜索连续的push指令
j = i - 1
while j >= 0 and insn_list[j].mnemonic == 'push':
j -= 1
if current_func:
functions.append(current_func)
current_func = {'start': insn_list[j + 1].address, 'end': None}
elif insn.mnemonic == 'mov' and insn.op_str == 'rbp, rsp':
if current_func:
functions.append(current_func)
current_func = {'start': insn.address, 'end': None}
if current_func:
current_func['end'] = insn.address + insn.size
i += 1
if current_func:
functions.append(current_func)
return functions
def find_function_containing_address(functions, address):
for func in functions:
if func['start'] <= address < func['end']:
return func
return None
# 限定范围
def get_section_range_rva(pe, section_name):
for section in pe.sections:
if section.Name.decode().strip('\x00') == section_name:
return section.VirtualAddress, section.VirtualAddress + section.SizeOfRawData
return None, None
def get_section_range_real(pe, section_name):
(start,end) = get_section_range_rva(pe, section_name)
if start and end:
start += pe.OPTIONAL_HEADER.ImageBase
end += pe.OPTIONAL_HEADER.ImageBase
return start, end
return None, None
def search_bytes(pe, start, end, bytes):
for i in range(start, end+1):
if pe.get_data(i, len(bytes)) == bytes:
return i
return None
def search_bytes_all(pe, start, end, bytes):
rva_list = []
for i in range(start, end+1):
if pe.get_data(i, len(bytes)) == bytes:
rva_list.append(i)
return rva_list
# 暴力引用查找 汇编分析?不存在的
def search_data_maybe_xref_all(pe, string_rva, start, end):
rva_list = []
for i in range(start, end+1):
if int.from_bytes(pe.get_data(i, 4), 'little',signed=True) + i + 4 == string_rva:
rva_list.append(i)
return rva_list
def search_data_maybe_xref(pe, string_rva, start, end):
for i in range(start, end+1):
if int.from_bytes(pe.get_data(i, 4), 'little',signed=True) + i + 4 == string_rva:
return i
return None
# search_data_maybe_xref和search_data_maybe_xref_all 忘记兼容上跳的情况了 已兼容
def search_call_maybe_xref(pe, string_rva, start, end):
for i in range(start, end+1):
if int.from_bytes(pe.get_data(i, 4), 'little',signed=True) + i + 4 == string_rva:
return i
return None
def search_data_pattern_all(pe, pattern, start, end):
rva_list = []
pattern = pattern.replace(' ', '').replace('0x', '').lower()
for i in range(start, end+1):
hex_data = ''.join(['%02x' % x for x in pe.get_data(i, len(pattern) // 2)])
for j in range(0, len(pattern)):
if pattern[j] != '?' and pattern[j] != hex_data[j]:
break
else:
rva_list.append(i)
return rva_list
def search_data_pattern(pe, pattern, start, end):
pattern = pattern.replace(' ', '').replace('0x', '').lower()
for i in range(start, end+1):
hex_data = ''.join(['%02x' % x for x in pe.get_data(i, len(pattern) // 2)])
for j in range(0, len(pattern)):
if pattern[j] != '?' and pattern[j] != hex_data[j]:
break
else:
return i
return None
def typeinfo_scan_all(pe, string_rva, start, end):
rva_list = []
for i in range(start, end+1):
if int.from_bytes(pe.get_data(i, 4), 'little',signed=True) + i + 4 == string_rva:
rva_list.append(i)
return rva_list
def get_all_call_range(pe, start, end):
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.skipdata = True
code = pe.get_data(start, end - start)
insn_list = list(md.disasm(code, start))
call_list = []
for insn in insn_list:
if insn.mnemonic == 'call':
# 计算被调用函数的地址
call_target = int(insn.op_str, 16)
call_list.append(call_target)
return call_list