def analyze(self, machO): symtabStruct = machO.makeStruct('4L') nlistStruct = machO.makeStruct('LBBH^') (symoff, nsyms, stroff, _) = peekStruct(machO.file, symtabStruct) # Get all nlist structs origin = machO.origin nlists = peekStructs(machO.file, nlistStruct, count=nsyms, position=symoff + origin) # Now analyze the nlist structs symbols = [] for (ordinal, (idx, typ, sect, desc, value)) in enumerate(nlists): string = peekString(machO.file, position=stroff + idx + origin) libord = (desc >> 8) & 0xff # GET_LIBRARY_ORDINAL extern = bool(typ & 1) # N_EXT symtype = SYMTYPE_GENERIC if (typ & 0xe) else SYMTYPE_UNDEFINED isThumb = bool(desc & 8) # N_ARM_THUMB_DEF if isThumb: value &= ~1 symbol = Symbol(string, value, symtype, ordinal, libord, extern, isThumb) symbols.append(symbol) # add those symbols back into the Mach-O. machO.addSymbols(symbols)
def analyze(self, machO): symtabStruct = machO.makeStruct('4L') nlistStruct = machO.makeStruct('LBBH^') (symoff, nsyms, stroff, _) = peekStruct(machO.file, symtabStruct) # Get all nlist structs origin = machO.origin nlists = peekStructs(machO.file, nlistStruct, count=nsyms, position=symoff+origin) # Now analyze the nlist structs symbols = [] for (ordinal, (idx, typ, sect, desc, value)) in enumerate(nlists): string = peekString(machO.file, position=stroff+idx+origin) libord = (desc >> 8) & 0xff # GET_LIBRARY_ORDINAL extern = bool(typ & 1) # N_EXT symtype = SYMTYPE_GENERIC if (typ & 0xe) else SYMTYPE_UNDEFINED isThumb = bool(desc & 8) # N_ARM_THUMB_DEF if isThumb: value &= ~1 symbol = Symbol(string, value, symtype, ordinal, libord, extern, isThumb) symbols.append(symbol) # add those symbols back into the Mach-O. machO.addSymbols(symbols)
def _exrelIter(self, machO, extreloff, count): reloc_res = peekStructs(machO.file, machO.makeStruct('LL'), count, position=extreloff + machO.origin) isBigEndian = machO.endian == '>' for r_address, r_extra in reloc_res: if r_address & 0x80000000: # it's a scattered_relocation_info raise MachOError( 'Analyzing scattered_relocation_info not implemented yet.') else: if isBigEndian: r_symbolnum = r_extra >> 8 r_extern = r_extra & 0x10 else: r_symbolnum = r_extra & 0xFFFFFF r_extern = r_extra & 0x8000000 if not r_extern: raise MachOError( 'Analyzing non-extern relocation not implemented yet.') yield (r_symbolnum, r_address)
def _loadSections(self, machO): segStruct = machO.makeStruct('16s4^2i2L') sectStruct = machO.makeStruct(Section.STRUCT_FORMAT) (segname, self.vmaddr, self._vmsize, self._fileoff, self._filesize, self.maxprot, self.initprot, nsects, _) = readStruct(machO.file, segStruct) self.segname = fromStringz(segname) machO_fileOrigin = machO._fileOrigin sectVals = peekStructs(machO.file, sectStruct, count=nsects) # get all section headers sectionsList = (Section.createSection(i) for i in sectVals ) # convert all headers into Section objects sections = DataTable('className', 'sectname', 'ftype') for s in sectionsList: if s.offset < machO_fileOrigin: s.offset += machO_fileOrigin sections.append(s, className=type(s).__name__, sectname=s.sectname, ftype=s.ftype) self.sections = sections self._hasAnalyzedSections = False self._shouldImportMappings = machO.mappings.mutable
def f(machO, vmaddr): if not vmaddr: return [] f = machO.file ms = machO.makeStruct pos = machO.fromVM(vmaddr) + machO.origin stru = ms(fmt1) count = peekStruct(f, stru, position=pos)[-1] # use fmt1 to obtain the count tuples = peekStructs(f, ms(fmt2), count, position=pos+stru.size) # use fmt2 to obtain the structures lst = [method(machO, s) for s in tuples] lst.reverse() return lst
def asStructs(self, stru, machO, includeAddresses=False): """Read the whole section as structs, and return an iterable of these. If *includeAddresses* is set to ``True``, return an iterable of (address, struct_content) tuples. """ count = self.size // stru.size structs = peekStructs(machO.file, stru, count=count, position=self.offset+machO.origin) if includeAddresses: addrs = range(self.addr, self.addr + self.size, stru.size) return zip(addrs, structs) else: return structs
def prepareMethodDescriptionList(machO, vmaddr): """Peek a ``objc_method_description_list`` struct at *vmaddr*, and return the ``objc_method_description``\\s as an iterable of 2-tuples.""" # struct objc_method_description_list { # int count; # struct objc_method_description list[1]; # }; if not vmaddr: return tuple() absfileoff = machO.fromVM(vmaddr) + machO.origin stru = machO.makeStruct('i') count = peekStruct(machO.file, stru, position=absfileoff)[0] return peekStructs(machO.file, machO.makeStruct('2^'), count, position=absfileoff+stru.size)
def get_atoms(opts, mo): try: spc_sym = mo.symbols.any1('name', '_stringpool_contents') wl_sym = mo.symbols.any1('name', '_wordlist') except KeyError as e: print("Error: Symbol '{0}' not found.".format(e.args[0])) return count = opts.atoms or (spc_sym.addr - wl_sym.addr) // 4 if count <= 0: print("Error: Word list count '{0}' is invalid.".format(count)) return mo.seek(mo.fromVM(wl_sym.addr)) for strindex, atom in peekStructs(mo.file, mo.makeStruct('2H'), count): if atom: yield (atom, mo.derefString(strindex + spc_sym.addr))
def asStructs(self, stru, machO, includeAddresses=False): """Read the whole section as structs, and return an iterable of these. If *includeAddresses* is set to ``True``, return an iterable of (address, struct_content) tuples. """ count = self.size // stru.size structs = peekStructs(machO.file, stru, count=count, position=self.offset + machO.origin) if includeAddresses: addrs = list(range(self.addr, self.addr + self.size, stru.size)) return list(zip(addrs, structs)) else: return structs
def _loadSections(self, machO): segStruct = machO.makeStruct('16s4^2i2L') sectStruct = machO.makeStruct(Section.STRUCT_FORMAT) (segname, self.vmaddr, self._vmsize, self._fileoff, self._filesize, self.maxprot, self.initprot, nsects, _) = readStruct(machO.file, segStruct) self.segname = fromStringz(segname) machO_fileOrigin = machO._fileOrigin sectVals = peekStructs(machO.file, sectStruct, count=nsects) # get all section headers sectionsList = (Section.createSection(i) for i in sectVals) # convert all headers into Section objects sections = DataTable('className', 'sectname', 'ftype') for s in sectionsList: if s.offset < machO_fileOrigin: s.offset += machO_fileOrigin sections.append(s, className=type(s).__name__, sectname=s.sectname, ftype=s.ftype) self.sections = sections self._hasAnalyzedSections = False self._shouldImportMappings = machO.mappings.mutable
def _exrelIter(self, machO, extreloff, count): reloc_res = peekStructs(machO.file, machO.makeStruct('LL'), count, position=extreloff+machO.origin) isBigEndian = machO.endian == '>' for r_address, r_extra in reloc_res: if r_address & 0x80000000: # it's a scattered_relocation_info raise MachOError('Analyzing scattered_relocation_info not implemented yet.') else: if isBigEndian: r_symbolnum = r_extra >> 8 r_extern = r_extra & 0x10 else: r_symbolnum = r_extra & 0xFFFFFF r_extern = r_extra & 0x8000000 if not r_extern: raise MachOError('Analyzing non-extern relocation not implemented yet.') yield (r_symbolnum, r_address)