Beispiel #1
0
    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)
Beispiel #2
0
	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)
Beispiel #3
0
    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)
Beispiel #4
0
    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
Beispiel #5
0
	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
Beispiel #6
0
	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
Beispiel #7
0
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)
Beispiel #8
0
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))
Beispiel #9
0
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))
Beispiel #10
0
    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
Beispiel #11
0
	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
Beispiel #12
0
	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)