Skip to content
This repository was archived by the owner on May 16, 2025. It is now read-only.

Commit abd18c8

Browse files
committed
Mac - provide proper symbol resolution when linkedit present
1 parent 69e0243 commit abd18c8

File tree

1 file changed

+36
-13
lines changed

1 file changed

+36
-13
lines changed

volatility/plugins/overlays/mac/macho.py

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -281,16 +281,24 @@ def __init__(self, theType, offset, vm, name = None, **kwargs):
281281
self.cached_dysymtab = None
282282
self.cached_syms = None
283283
self.load_diff = 0
284+
self.link_edit_bias = 0
284285

285286
macho.__init__(self, 1, "macho32_header", "macho64_header", theType, offset, vm, name, **kwargs)
286287

287288
if self.macho_obj:
288-
self._build_symbol_caches()
289289
self.calc_load_diff()
290+
self._calc_linkedit_bias()
291+
self._build_symbol_caches()
290292

291293
def is_valid(self):
292294
return self.macho_obj != None
293295

296+
def _calc_linkedit_bias(self):
297+
for s in self.segments():
298+
if str(s.segname) == "__LINKEDIT":
299+
self.link_edit_bias = s.vmaddr - s.fileoff
300+
break
301+
294302
def calc_load_diff(self):
295303
seg = None
296304

@@ -314,7 +322,6 @@ def load_commands(self):
314322

315323
# the load commands start after the header
316324
hdr_size = self.macho_obj.size()
317-
318325
if hdr_size == 0 or hdr_size > 100000000:
319326
return
320327

@@ -358,16 +365,24 @@ def get_indirect_syms(self):
358365
tname = self._get_typename("nlist")
359366
obj_size = self.obj_vm.profile.get_obj_size(tname)
360367

368+
indirect_table_addr = self.link_edit_bias + self.cached_dysymtab.indirectsymoff
369+
370+
if not self.obj_vm.is_valid_address(indirect_table_addr):
371+
return syms
372+
361373
cnt = self.cached_dysymtab.nindirectsyms
362374
if cnt > 100000:
363375
cnt = 1024
364-
365-
symtab_idxs = obj.Object(theType="Array", targetType="unsigned int", count=cnt, offset = self.obj_offset + self.cached_dysymtab.indirectsymoff, vm = self.obj_vm, parent = self)
376+
377+
symtab_idxs = obj.Object(theType="Array", targetType="unsigned int", count=cnt,
378+
offset = indirect_table_addr,
379+
vm = self.obj_vm, parent = self)
366380

367381
for idx in symtab_idxs:
368382
sym_addr = self.cached_symtab + (idx * obj_size)
369383
sym = obj.Object("macho_nlist", offset = sym_addr, vm = self.obj_vm, parent = self)
370-
syms.append(sym)
384+
if sym.is_valid():
385+
syms.append(sym)
371386

372387
return syms
373388

@@ -376,10 +391,18 @@ def _get_symtab_syms(self, sym_command, symtab_addr):
376391
tname = self._get_typename("nlist")
377392
obj_size = self.obj_vm.profile.get_obj_size(tname)
378393

379-
for i in range(sym_command.nsyms):
394+
if not self.obj_vm.is_valid_address(symtab_addr):
395+
return syms
396+
397+
num_syms = sym_command.nsyms
398+
if num_syms > 2000:
399+
return syms
400+
401+
for i in range(num_syms):
380402
sym_addr = symtab_addr + (i * obj_size)
381403
sym = obj.Object("macho_nlist", offset = sym_addr, vm = self.obj_vm, parent = self)
382-
syms.append(sym)
404+
if sym.is_valid():
405+
syms.append(sym)
383406

384407
return syms
385408

@@ -391,16 +414,16 @@ def _build_symbol_caches(self):
391414
return
392415

393416
symtab_command = symtab_cmd.cast(symtab_struct_name)
394-
str_strtab = self.obj_offset + symtab_command.stroff
395-
symtab_addr = self.obj_offset + symtab_command.symoff
396-
417+
str_strtab = self.link_edit_bias + symtab_command.stroff
418+
symtab_addr = self.link_edit_bias + symtab_command.symoff
419+
397420
self.cached_syms = self._get_symtab_syms(symtab_command, symtab_addr)
398-
421+
399422
dysymtab_cmd = self.load_command_of_type(0xb) # LC_DYSYMTAB
400-
dystruct_name = self._get_typename("dysymtab_command")
401-
402423
if dysymtab_cmd == None:
403424
return
425+
426+
dystruct_name = self._get_typename("dysymtab_command")
404427
dysymtab_command = dysymtab_cmd.cast(dystruct_name)
405428

406429
self.cached_strtab = str_strtab

0 commit comments

Comments
 (0)