6
6
from elftools .elf .relocation import RelocationSection
7
7
from elftools .elf .sections import SymbolTableSection
8
8
from elftools .elf .sections import StringTableSection
9
+ from elftools .elf .constants import SH_FLAGS
10
+ from elftools .construct import Container
9
11
import elftools .elf .sections
10
12
from unicorn import UC_PROT_ALL
11
13
@@ -47,13 +49,25 @@ def find_module(self, addr):
47
49
if module .base == addr :
48
50
return module
49
51
return None
50
-
51
- def find_section_index (self , elf , addr ):
52
+
53
+ @staticmethod
54
+ def find_section_index (elf , addr ):
52
55
for idx , section in enumerate (elf .iter_sections ()):
53
56
if section .header ['sh_addr' ] <= addr < (section .header ['sh_addr' ] + section .header ['sh_size' ]):
54
57
return idx
55
58
return 0
56
59
60
+ @staticmethod
61
+ def calculate_sh_offset (elf , vaddr ):
62
+ for segment in elf .iter_segments ():
63
+ if segment .header .p_type == 'PT_LOAD' :
64
+ p_vaddr = segment .header .p_vaddr
65
+ p_offset = segment .header .p_offset
66
+ p_filesz = segment .header .p_filesz
67
+ if p_vaddr <= vaddr < (p_vaddr + p_filesz ):
68
+ return p_offset + (vaddr - p_vaddr )
69
+ raise Exception (f"Cannot find segment containing address { vaddr :#x} " )
70
+
57
71
def load_module (self , filename ):
58
72
logger .debug ("Loading module '%s'." % filename )
59
73
@@ -174,18 +188,18 @@ def load_module(self, filename):
174
188
175
189
if has_reloc_info and active_rel ['addr' ] and active_rel ['size' ] and active_rel ['entsize' ]:
176
190
is_rela = rel_info ['type' ] == 'RELA'
177
- fake_rel_header = {
178
- ' sh_name' : 0 , # we don't know the name
179
- ' sh_type' : 'SHT_RELA' if is_rela else 'SHT_REL' ,
180
- ' sh_flags' : 2 ,
181
- ' sh_addr' : active_rel ['addr' ],
182
- ' sh_offset' : active_rel ['addr' ],
183
- ' sh_size' : active_rel ['size' ],
184
- ' sh_link' : rel_info ['sym' ], # link to dynsym
185
- ' sh_info' : 0 ,
186
- ' sh_addralign' : 8 if elf .elfclass == 64 else 4 ,
187
- ' sh_entsize' : active_rel ['entsize' ]
188
- }
191
+ fake_rel_header = Container (
192
+ sh_name = 0 , # we don't know the name
193
+ sh_type = 'SHT_RELA' if is_rela else 'SHT_REL' ,
194
+ sh_flags = SH_FLAGS . SHF_ALLOC ,
195
+ sh_addr = active_rel ['addr' ],
196
+ sh_offset = self . calculate_sh_offset ( elf , active_rel ['addr' ]) ,
197
+ sh_size = active_rel ['size' ],
198
+ sh_link = rel_info ['sym' ], # link to dynsym
199
+ sh_info = 0 ,
200
+ sh_addralign = 8 if elf .elfclass == 64 else 4 ,
201
+ sh_entsize = active_rel ['entsize' ]
202
+ )
189
203
rel_section = RelocationSection (fake_rel_header ,
190
204
'.rela.dyn' if is_rela else '.rel.dyn' ,
191
205
elf )
@@ -197,34 +211,34 @@ def load_module(self, filename):
197
211
sym_info ['dynsym' ]['size' ] = sym_info ['dynstr' ]['addr' ] - sym_info ['dynsym' ]['addr' ]
198
212
199
213
if dynstr is None and sym_info ['dynstr' ]['addr' ] and sym_info ['dynstr' ]['size' ]:
200
- fake_str_header = {
201
- ' sh_name' : 0 ,
202
- ' sh_type' : 'SHT_STRTAB' ,
203
- ' sh_flags' : 2 ,
204
- ' sh_addr' : sym_info ['dynstr' ]['addr' ],
205
- ' sh_offset' : sym_info ['dynstr' ]['addr' ],
206
- ' sh_size' : sym_info ['dynstr' ]['size' ],
207
- ' sh_link' : 0 ,
208
- ' sh_info' : 0 ,
209
- ' sh_addralign' : 1 ,
210
- ' sh_entsize' : 0
211
- }
214
+ fake_str_header = Container (
215
+ sh_name = 0 ,
216
+ sh_type = 'SHT_STRTAB' ,
217
+ sh_flags = SH_FLAGS . SHF_ALLOC ,
218
+ sh_addr = sym_info ['dynstr' ]['addr' ],
219
+ sh_offset = self . calculate_sh_offset ( elf , sym_info ['dynstr' ]['addr' ]) ,
220
+ sh_size = sym_info ['dynstr' ]['size' ],
221
+ sh_link = 0 ,
222
+ sh_info = 0 ,
223
+ sh_addralign = 1 ,
224
+ sh_entsize = 0
225
+ )
212
226
dynstr = StringTableSection (fake_str_header , '.dynstr' , elf )
213
227
214
228
if dynsym is None and dynstr is not None and \
215
229
sym_info ['dynsym' ]['addr' ] and sym_info ['dynsym' ]['size' ]:
216
- fake_sym_header = {
217
- ' sh_name' : 0 ,
218
- ' sh_type' : 'SHT_DYNSYM' ,
219
- ' sh_flags' : 2 ,
220
- ' sh_addr' : sym_info ['dynsym' ]['addr' ],
221
- ' sh_offset' : sym_info ['dynsym' ]['addr' ],
222
- ' sh_size' : sym_info ['dynsym' ]['size' ],
223
- ' sh_link' : self .find_section_index (elf , sym_info ['dynstr' ]['addr' ]), # link to dynstr
224
- ' sh_info' : 0 , # we don't know the index of the first non-local symbol
225
- ' sh_addralign' : 8 if elf .elfclass == 64 else 4 ,
226
- ' sh_entsize' : sym_info ['dynsym' ]['entsize' ]
227
- }
230
+ fake_sym_header = Container (
231
+ sh_name = 0 ,
232
+ sh_type = 'SHT_DYNSYM' ,
233
+ sh_flags = SH_FLAGS . SHF_ALLOC ,
234
+ sh_addr = sym_info ['dynsym' ]['addr' ],
235
+ sh_offset = self . calculate_sh_offset ( elf , sym_info ['dynsym' ]['addr' ]) ,
236
+ sh_size = sym_info ['dynsym' ]['size' ],
237
+ sh_link = self .find_section_index (elf , sym_info ['dynstr' ]['addr' ]), # link to dynstr
238
+ sh_info = 0 , # we don't know the index of the first non-local symbol
239
+ sh_addralign = 8 if elf .elfclass == 64 else 4 ,
240
+ sh_entsize = sym_info ['dynsym' ]['entsize' ]
241
+ )
228
242
dynsym = SymbolTableSection (fake_sym_header , '.dynsym' , elf , dynstr )
229
243
230
244
# Find init array.
0 commit comments