def readExports(self) -> None:
        """
		Gets export symbols
		"""

        self.exports = []

        # try to get exports by LC_DYLD_INFO
        dyldInfo = self.machoFile.getLoadCommand(
            (MachO.LoadCommands.LC_DYLD_INFO,
             MachO.LoadCommands.LC_DYLD_INFO_ONLY))
        if dyldInfo:
            self.exports = MachO.TrieParser(dyldInfo.exportData).parse()
        else:
            # try to get exports by LC_DYLD_EXPORTS_TRIE
            exportsTrie = self.machoFile.getLoadCommand(
                MachO.LoadCommands.LC_DYLD_EXPORTS_TRIE)
            if exportsTrie:
                self.exports = MachO.TrieParser(
                    exportsTrie.linkeditData).parse()
            else:
                logging.warning("Unable to get export data.")

        # remove any non ReExport symbols
        reExportDeps = []
        deps = self.machoFile.getLoadCommand(
            (MachO.LoadCommands.LC_LOAD_DYLIB,
             MachO.LoadCommands.LC_LOAD_WEAK_DYLIB,
             MachO.LoadCommands.LC_REEXPORT_DYLIB,
             MachO.LoadCommands.LC_LOAD_UPWARD_DYLIB),
            multiple=True)
        if deps:
            depIndex = 0
            for dep in deps:
                depIndex += 1
                if dep.cmd == MachO.LoadCommands.LC_REEXPORT_DYLIB:
                    reExportDeps.append(depIndex)

        def isReExport(entry: MachO.TrieEntry) -> bool:
            if (entry.flags & MachO.Export.EXPORT_SYMBOL_FLAGS_KIND_MASK
                ) != MachO.Export.EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
                return True
            if (entry.flags & MachO.Export.EXPORT_SYMBOL_FLAGS_REEXPORT) == 0:
                return True
            if entry.other in reExportDeps:
                return True
            return False

        self.exports = [
            export for export in self.exports if isReExport(export)
        ]
        pass
Esempio n. 2
0
    def lookupSymbol(self, addr: int) -> bytes:
        """
			Given the VMAddress of an exported function,
			this method will return its symbol name.
		"""

        if addr in self.symbolCache:
            return self.symbolCache[addr]

        # find the image with the address and cache its exports.
        for image in self.imageCache:
            if image.containsAddr(addr):
                dyldInfo = image.getLoadCommand(
                    (MachO.LoadCommands.LC_DYLD_INFO,
                     MachO.LoadCommands.LC_DYLD_INFO_ONLY))
                dyldInfo.loadData()

                imageTextSeg = image.getSegment(b"__TEXT\x00")

                exports = MachO.TrieParser(dyldInfo.exportData).parse()
                for export in exports:
                    exportAddr = imageTextSeg.vmaddr + export.address
                    self.symbolCache[exportAddr] = export.name
                break

        # look for the symbol again
        if addr in self.symbolCache:
            return self.symbolCache[addr]
        else:
            return None
    def readExports(self) -> None:
        """
		Gets export symbols
		"""

        exportData = self.machoFile.getLoadCommand(
            (MachO.LoadCommands.LC_DYLD_INFO,
             MachO.LoadCommands.LC_DYLD_INFO_ONLY)).exportData
        self.exports = MachO.TrieParser(exportData).parse()

        # remove any non ReExport symbols
        reExportDeps = []
        deps = self.machoFile.getLoadCommand(
            (MachO.LoadCommands.LC_LOAD_DYLIB,
             MachO.LoadCommands.LC_LOAD_WEAK_DYLIB,
             MachO.LoadCommands.LC_REEXPORT_DYLIB,
             MachO.LoadCommands.LC_LOAD_UPWARD_DYLIB),
            multiple=True)
        if deps:
            depIndex = 0
            for dep in deps:
                depIndex += 1
                if dep.cmd == MachO.LoadCommands.LC_REEXPORT_DYLIB:
                    reExportDeps.append(depIndex)

        def isReExport(entry: MachO.TrieEntry) -> bool:
            if (entry.flags & MachO.Export.EXPORT_SYMBOL_FLAGS_KIND_MASK
                ) != MachO.Export.EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
                return True
            if (entry.flags & MachO.Export.EXPORT_SYMBOL_FLAGS_REEXPORT) == 0:
                return True
            if entry.other in reExportDeps:
                return True
            return False

        self.exports = [
            export for export in self.exports if isReExport(export)
        ]
        pass