@@ -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