Skip to content

Commit 83b2f95

Browse files
author
WangONC
committed
Fix some issues, make the code more rigorous
1 parent 36953a1 commit 83b2f95

File tree

1 file changed

+52
-38
lines changed

1 file changed

+52
-38
lines changed

src/androidemu/internal/modules.py

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from elftools.elf.relocation import RelocationSection
77
from elftools.elf.sections import SymbolTableSection
88
from elftools.elf.sections import StringTableSection
9+
from elftools.elf.constants import SH_FLAGS
10+
from elftools.construct import Container
911
import elftools.elf.sections
1012
from unicorn import UC_PROT_ALL
1113

@@ -47,13 +49,25 @@ def find_module(self, addr):
4749
if module.base == addr:
4850
return module
4951
return None
50-
51-
def find_section_index(self, elf, addr):
52+
53+
@staticmethod
54+
def find_section_index(elf, addr):
5255
for idx, section in enumerate(elf.iter_sections()):
5356
if section.header['sh_addr'] <= addr < (section.header['sh_addr'] + section.header['sh_size']):
5457
return idx
5558
return 0
5659

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+
5771
def load_module(self, filename):
5872
logger.debug("Loading module '%s'." % filename)
5973

@@ -174,18 +188,18 @@ def load_module(self, filename):
174188

175189
if has_reloc_info and active_rel['addr'] and active_rel['size'] and active_rel['entsize']:
176190
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+
)
189203
rel_section = RelocationSection(fake_rel_header,
190204
'.rela.dyn' if is_rela else '.rel.dyn',
191205
elf)
@@ -197,34 +211,34 @@ def load_module(self, filename):
197211
sym_info['dynsym']['size'] = sym_info['dynstr']['addr'] - sym_info['dynsym']['addr']
198212

199213
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+
)
212226
dynstr = StringTableSection(fake_str_header, '.dynstr', elf)
213227

214228
if dynsym is None and dynstr is not None and \
215229
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+
)
228242
dynsym = SymbolTableSection(fake_sym_header, '.dynsym', elf, dynstr)
229243

230244
# Find init array.

0 commit comments

Comments
 (0)