Repository navigation
Expand file tree
/
Copy pathquickScanElf.py
More file actions
211 lines (188 loc) · 8.19 KB
/
Copy pathquickScanElf.py
File metadata and controls
211 lines (188 loc) · 8.19 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
from elftools.elf.elffile import ELFFile
from capstone import *
def find_symbol_in_got_plt(elf,symbol_name):
symtab = elf.get_section_by_name('.dynsym')
if not symtab:
print("符号表不存在")
return None
rel_section = elf.get_section_by_name('.rela.plt')
if rel_section:
for rel in rel_section.iter_relocations():
r_info = rel.entry['r_info']
rel_symbol_index = r_info >> 32
rel_symbol = symtab.get_symbol(rel_symbol_index)
if rel_symbol.name == symbol_name:
symbol_address = rel['r_offset']
return symbol_address
print(f"符号 {symbol_name} 不在段中")
return None
def get_text_section(elf):
for section in elf.iter_sections():
if section.name == '.text':
return section
return None
def get_function_ranges(elf):
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.skipdata = True
text_section = get_text_section(elf)
code = text_section.data()
start_addr = text_section['sh_addr']
end_addr = start_addr + text_section['sh_size']
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':
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(elf, section_name):
for section in elf.iter_sections():
if section.name == section_name:
return section['sh_addr'], section['sh_addr'] + section['sh_size']
return None, None
def search_bytes(elf, start, end, bytes):
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
data = section.data()
offset = start - section['sh_addr']
for i in range(offset, offset + (end - start + 1)):
if data[i:i + len(bytes)] == bytes:
return section['sh_addr'] + i
return None
def search_bytes_all(elf, start, end, bytes):
rva_list = []
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
data = section.data()
offset = start - section['sh_addr']
for i in range(offset, offset + (end - start + 1)):
if data[i:i + len(bytes)] == bytes:
rva_list.append(section['sh_addr'] + i)
return rva_list
def search_data_pattern_all(elf, pattern, start, end):
rva_list = []
pattern = pattern.replace(' ', '').replace('0x', '').lower()
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
data = section.data()
offset = start - section['sh_addr']
for i in range(offset, offset + (end - start + 1)):
hex_data = ''.join(['%02x' % x for x in data[i: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(section['sh_addr'] + i)
return rva_list
def search_data_pattern(elf, pattern, start, end):
pattern = pattern.replace(' ', '').replace('0x', '').lower()
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
data = section.data()
offset = start - section['sh_addr']
for i in range(offset, offset + (end - start + 1)):
hex_data = ''.join(['%02x' % x for x in data[i:i + len(pattern) // 2]])
for j in range(0, len(pattern)):
if pattern[j] != '?' and pattern[j] != hex_data[j]:
break
else:
return section['sh_addr'] + i
return None
def search_data_maybe_xref(elf, string_rva, start, end):
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
data = section.data()
offset = start - section['sh_addr']
for i in range(offset, offset + (end - start + 1)):
if int.from_bytes(data[i:i + 4], 'little', signed=True) + section['sh_addr'] + i + 4 == string_rva:
return section['sh_addr'] + i
return None
def search_data_maybe_xref_pattern(elf, pattern, string_rva, start, end):
pattern = pattern.replace(' ', '').replace('0x', '').lower()
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
data = section.data()
offset = start - section['sh_addr']
for i in range(offset, offset + (end - start + 1)):
pattern_len = len(pattern) // 2
hex_data = ''.join(['%02x' % x for x in data[i:i + pattern_len]]) # hex + 4字节偏移
for j in range(0, len(pattern)):
if pattern[j] != '?' and pattern[j] != hex_data[j]:
break
else:
if int.from_bytes(data[i+pattern_len:i + 4+pattern_len], 'little', signed=True) + section['sh_addr'] + i + 4 + pattern_len == string_rva:
return section['sh_addr'] + i + pattern_len
return None
def search_data_maybe_xref_all(elf, string_rva, start, end):
rva_list = []
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
data = section.data()
offset = start - section['sh_addr']
for i in range(offset, offset + (end - start + 1)):
if int.from_bytes(data[i:i + 4], 'little', signed=True) + section['sh_addr'] + i + 4 == string_rva:
rva_list.append(section['sh_addr'] + i)
return rva_list
def get_all_call_range(elf, start, end):
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.skipdata = True
code = b''
for section in elf.iter_sections():
if section['sh_addr'] <= start < section['sh_addr'] + section['sh_size']:
offset = start - section['sh_addr']
code = section.data()[offset:offset + (end - start)]
break
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
def get_all_push_range(elf, start, end):
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.skipdata = True
code = elf.get_section_by_name('.text').data()[start:end]
push_count = 0
for insn in md.disasm(code, start):
if insn.mnemonic == 'push':
push_count += 1
return push_count
def get_function_param_count(elf, start, end):
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.detail = True
md.skipdata = True
code = elf.get_section_by_name('.text').data()[start:end]
param_count = 0
registers = ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9']
used_registers = set()
for insn in md.disasm(code, start):
if insn.mnemonic == 'push':
param_count += 1
elif insn.mnemonic == 'mov' and insn.operands[0].type == CS_OP_REG:
reg_name = insn.reg_name(insn.operands[0].reg)
if reg_name in registers and reg_name not in used_registers:
used_registers.add(reg_name)
param_count += 1
return param_count