Ejemplo n.º 1
0
	
	.. attribute:: cryptid
	
		The method of encryption.
	
	"""

	def analyze(self, machO):
		(self.cryptoff, self.cryptsize, self.cryptid) = machO.readFormatStruct('3L')
			
	def __str__(self):
		return "<EncryptionInfo {}/{:x}>".format(self.cryptid, self.cryptoff)

	def encrypted(self, offset):
		"""Checks if the offset is encrypted."""
		return self.cryptid != 0 and self.cryptoff <= offset < self.cryptoff + self.cryptsize


LoadCommand.registerFactory(LC_ENCRYPTION_INFO, EncryptionInfoCommand)

@patch
class MachO_EncryptionPatches(MachO):
	"""This patch defines a single convenient function :meth:`encrypted` which
	can check if a file offset is encrypted."""

	def encrypted(self, fileoff):
		"""Checks if the file offset is in any encrypted region."""
		encCmds = self.loadCommands.all('className', 'EncryptionInfoCommand')
		return any(lc.encrypted(fileoff) for lc in encCmds)

Ejemplo n.º 2
0
	
	"""
    def analyze(self, machO):
        (offset, self.timestamp, self.version,
         self.minVersion) = peekStruct(machO.file, machO.makeStruct('4L'))
        self.name = peekString(machO.file,
                               position=offset + machO.origin + self.offset -
                               8)

    def __str__(self):
        return "<Dylib {!r}>".format(self.name)


for i in (LC_LOAD_DYLIB, LC_ID_DYLIB, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB,
          LC_LAZY_LOAD_DYLIB, LC_LOAD_UPWARD_DYLIB):
    LoadCommand.registerFactory(i, DylibCommand)


@patch
class MachO_FromLibord(MachO):
    """This patch defines a single convenient function :meth:`dylibFromLibord`
	which can convert a library ordinal to a :class:`DylibCommand` object."""
    def dylibFromLibord(self, libord):
        """Converts library ordinal to a :class:`DylibCommand` object. Returns
		``None`` if the input is invalid."""

        if libord < 0:
            return None

        lcs = self.loadCommands
        if not libord:
Ejemplo n.º 3
0
		if not all(lc.isAnalyzed for lc in machO.loadCommands.all('className', 'SymtabCommand')):
			return True
	
		(     ilocalsym,      nlocalsym,
		      iextdefsym,     nextdefsym,
		      iundefsym,      nundefsym,
		      tocoff,         ntoc,
		      modtaboff,      nmodtab,
		      extrefsymoff,   nextrefsyms,
		 self.indirectsymoff, nindirectsyms,
		      extreloff,      nextrel,
		      locreloff,      nlocrel) = peekStruct(machO.file, machO.makeStruct('18L'))
		
		if nextrel:
			machO.provideAddresses(self._exrelIter(machO, extreloff, nextrel))
	
	
	def indirectSymbols(self, start, count, machO):
		'''Get symbol indices from the indirect symbol table, given the *start*
		index and the *count* of indices to retrieve.'''
		
		offset = self.indirectsymoff + start * 4 + machO.origin
		return peekPrimitives(machO.file, 'L', count, machO.endian, machO.is64bit, position=offset)
		

LoadCommand.registerFactory(LC_DYSYMTAB, DySymtabCommand)




Ejemplo n.º 4
0
        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)


LoadCommand.registerFactory(LC_SYMTAB, SymtabCommand)
Ejemplo n.º 5
0
		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)

LoadCommand.registerFactory(LC_SYMTAB, SymtabCommand)




Ejemplo n.º 6
0
	
	.. attribute:: minVersion
	
		The compatibility version of the dynamic library.
	
	"""

	def analyze(self, machO):
		(offset, self.timestamp, self.version, self.minVersion) = peekStruct(machO.file, machO.makeStruct('4L'))
		self.name = peekString(machO.file, position=offset + machO.origin + self.offset - 8)
			
	def __str__(self):
		return "<Dylib {!r}>".format(self.name)

for i in (LC_LOAD_DYLIB, LC_ID_DYLIB, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LAZY_LOAD_DYLIB, LC_LOAD_UPWARD_DYLIB):
	LoadCommand.registerFactory(i, DylibCommand)

@patch
class MachO_FromLibord(MachO):
	"""This patch defines a single convenient function :meth:`dylibFromLibord`
	which can convert a library ordinal to a :class:`DylibCommand` object."""
	
	def dylibFromLibord(self, libord):
		"""Converts library ordinal to a :class:`DylibCommand` object. Returns
		``None`` if the input is invalid."""
		
		if libord < 0:
			return None
		
		lcs = self.loadCommands
		if not libord:
Ejemplo n.º 7
0
		allSegments = machO.loadCommands.all('className', type(self).__name__)
		if not all(hasattr(seg, 'vmaddr') for seg in allSegments):
			return True
		
		# now analyze the sections.
		if not self._hasAnalyzedSections:
			self._analyzeSections(machO)
				
	
	def __str__(self):
		return "<Segment: {} [{}]>".format(self.segname, ', '.join(map(str, self._sections.values())))


	

LoadCommand.registerFactory(LC_SEGMENT, SegmentCommand)
LoadCommand.registerFactory(LC_SEGMENT_64, SegmentCommand)


@patch
class MachO_SegmentCommandPatches(MachO):
	"""This patch to the :class:`~macho.macho.MachO` class defines several
	methods that operate over all segments."""

	def segment(self, segname):
		"""Find a :class:`SegmentCommand` with the specified *segname*."""
		for segment in self.loadCommands.all('className', 'SegmentCommand'):
			if segment.segname == segname:
				return segment
		return None
Ejemplo n.º 8
0
		The size of this encryption region.
	
	.. attribute:: cryptid
	
		The method of encryption.
	
	"""
    def analyze(self, machO):
        (self.cryptoff, self.cryptsize,
         self.cryptid) = machO.readFormatStruct('3L')

    def __str__(self):
        return "<EncryptionInfo {}/{:x}>".format(self.cryptid, self.cryptoff)

    def encrypted(self, offset):
        """Checks if the offset is encrypted."""
        return self.cryptid != 0 and self.cryptoff <= offset < self.cryptoff + self.cryptsize


LoadCommand.registerFactory(LC_ENCRYPTION_INFO, EncryptionInfoCommand)


@patch
class MachO_EncryptionPatches(MachO):
    """This patch defines a single convenient function :meth:`encrypted` which
	can check if a file offset is encrypted."""
    def encrypted(self, fileoff):
        """Checks if the file offset is in any encrypted region."""
        encCmds = self.loadCommands.all('className', 'EncryptionInfoCommand')
        return any(lc.encrypted(fileoff) for lc in encCmds)
Ejemplo n.º 9
0
                yield (r_symbolnum, r_address)

    def analyze(self, machO):
        # Make sure the SYMTAB command is ready.
        if not all(lc.isAnalyzed for lc in machO.loadCommands.all(
                'className', 'SymtabCommand')):
            return True

        (ilocalsym, nlocalsym, iextdefsym, nextdefsym, iundefsym, nundefsym,
         tocoff, ntoc, modtaboff, nmodtab, extrefsymoff, nextrefsyms,
         self.indirectsymoff, nindirectsyms, extreloff, nextrel, locreloff,
         nlocrel) = peekStruct(machO.file, machO.makeStruct('18L'))

        if nextrel:
            machO.provideAddresses(self._exrelIter(machO, extreloff, nextrel))

    def indirectSymbols(self, start, count, machO):
        '''Get symbol indices from the indirect symbol table, given the *start*
		index and the *count* of indices to retrieve.'''

        offset = self.indirectsymoff + start * 4 + machO.origin
        return peekPrimitives(machO.file,
                              'L',
                              count,
                              machO.endian,
                              machO.is64bit,
                              position=offset)


LoadCommand.registerFactory(LC_DYSYMTAB, DySymtabCommand)
Ejemplo n.º 10
0
        # make sure all segments are ready
        allSegments = machO.loadCommands.all('className', type(self).__name__)
        if not all(hasattr(seg, 'vmaddr') for seg in allSegments):
            return True

        # now analyze the sections.
        if not self._hasAnalyzedSections:
            self._analyzeSections(machO)

    def __str__(self):
        return "<Segment: {} [{}]>".format(
            self.segname, ', '.join(map(str, list(self._sections.values()))))


LoadCommand.registerFactory(LC_SEGMENT, SegmentCommand)
LoadCommand.registerFactory(LC_SEGMENT_64, SegmentCommand)


@patch
class MachO_SegmentCommandPatches(MachO):
    """This patch to the :class:`~macho.macho.MachO` class defines several
	methods that operate over all segments."""
    def segment(self, segname):
        """Find a :class:`SegmentCommand` with the specified *segname*."""
        for segment in self.loadCommands.all('className', 'SegmentCommand'):
            if segment.segname == segname:
                return segment
        return None

    def allSections(self, idtype, sectid):