Example #1
0
 def __init__(self, filename=None):
     self.header = MachOHeader()
     self.segments = []
     self.commands = []
     if filename is not None:
         with open(filename, "rb") as macho_file:
             self.load_file(macho_file)
Example #2
0
 def __init__(self, filename=None):
     self.header = MachOHeader()
     self.segments = []
     self.commands = []
     if filename is not None:
         with open(filename, "rb") as macho_file:
             self.load_file(macho_file)
Example #3
0
 def load_file(self, macho_file):
     self.header = MachOHeader(macho_file)
     self.load_commands(macho_file)
Example #4
0
class MachO(object):
    """
    Represent a Mach-O file
    """

    header = None
    segments = None
    commands = None

    def __init__(self, filename=None):
        self.header = MachOHeader()
        self.segments = []
        self.commands = []
        if filename is not None:
            with open(filename, "rb") as macho_file:
                self.load_file(macho_file)

    def load_file(self, macho_file):
        self.header = MachOHeader(macho_file)
        self.load_commands(macho_file)

    def write_file(self, filename):
        with open(filename, "wb") as macho_file:
            self.header.write(macho_file)
            for segment in self.segments:
                segment.write(macho_file)
            for command in self.commands:
                command.write(macho_file)

    def load_commands(self, macho_file):
        assert macho_file.tell() == 28 or macho_file.tell() == 32
        for i in range(self.header.ncmds):
            cmd, cmdsize = unpack('<II', macho_file.read(4*2))
            if cmd == LC_SEGMENT:
                self.segments.append(MachOSegment(macho_file))
            elif cmd == LC_SEGMENT_64:
                self.segments.append(MachOSegment(macho_file, arch=64))
            elif cmd in [LC_DYLD_INFO_ONLY, LC_DYLD_INFO]:
                self.commands.append(MachODYLDInfoCommand(macho_file, cmd))
            elif cmd == LC_SYMTAB:
                self.commands.append(MachOSymtabCommand(macho_file, cmd, is_64=self.header.is_64()))
            elif cmd == LC_DYSYMTAB:
                self.commands.append(MachODYSymtabCommand(macho_file, cmd))
            elif cmd in [LC_LOAD_DYLINKER, LC_DYLD_ENVIRONMENT]:
                self.commands.append(MachODYLinkerCommand(macho_file, cmd, is_64=self.header.is_64()))
            elif cmd == LC_UUID:
                self.commands.append(MachOUUIDCommand(macho_file, cmd))
            elif cmd in [LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS]:
                self.commands.append(MachOVersionMinCommand(macho_file, cmd))
            elif cmd in [LC_UNIXTHREAD, LC_THREAD]:
                self.commands.append(MachOThreadCommand(macho_file, cmd))
            elif cmd == LC_MAIN:
                self.commands.append(MachOMainCommand(macho_file, cmd))
            elif cmd in [LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_ID_DYLIB]:
                self.commands.append(MachOLoadDYLibCommand(macho_file, cmd))
            elif cmd in [LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS]:
                self.commands.append(MachOLinkeditDataCommand(macho_file, cmd))
            elif cmd == LC_RPATH:
                self.commands.append(MachORPathCommand(macho_file, cmd))
            elif cmd == LC_SOURCE_VERSION:
                self.commands.append(MachOSourceVersionCommand(macho_file, cmd))
            elif cmd == LC_ENCRYPTION_INFO:
                self.commands.append(MachOEncryptionInfoCommand(macho_file, cmd))
            else:
                raise Exception("unknow load command : 0x%x - please report it!" % cmd)
Example #5
0
 def load_file(self, macho_file):
     self.header = MachOHeader(macho_file)
     self.load_commands(macho_file)
Example #6
0
class MachO(object):
    """
    Represent a Mach-O file
    """

    header = None
    segments = None
    commands = None

    def __init__(self, filename=None):
        self.header = MachOHeader()
        self.segments = []
        self.commands = []
        if filename is not None:
            with open(filename, "rb") as macho_file:
                self.load_file(macho_file)

    def load_file(self, macho_file):
        self.header = MachOHeader(macho_file)
        self.load_commands(macho_file)

    def write_file(self, filename):
        with open(filename, "wb") as macho_file:
            self.header.write(macho_file)
            for segment in self.segments:
                segment.write(macho_file)
            for command in self.commands:
                command.write(macho_file)

    def load_commands(self, macho_file):
        assert macho_file.tell() == 28 or macho_file.tell() == 32
        for i in range(self.header.ncmds):
            cmd, cmdsize = unpack('<II', macho_file.read(4 * 2))
            if cmd == LC_SEGMENT:
                self.segments.append(MachOSegment(macho_file))
            elif cmd == LC_SEGMENT_64:
                self.segments.append(MachOSegment(macho_file, arch=64))
            elif cmd in [LC_DYLD_INFO_ONLY, LC_DYLD_INFO]:
                self.commands.append(MachODYLDInfoCommand(macho_file, cmd))
            elif cmd == LC_SYMTAB:
                self.commands.append(
                    MachOSymtabCommand(macho_file,
                                       cmd,
                                       is_64=self.header.is_64()))
            elif cmd == LC_DYSYMTAB:
                self.commands.append(MachODYSymtabCommand(macho_file, cmd))
            elif cmd in [LC_LOAD_DYLINKER, LC_DYLD_ENVIRONMENT]:
                self.commands.append(
                    MachODYLinkerCommand(macho_file,
                                         cmd,
                                         is_64=self.header.is_64()))
            elif cmd == LC_UUID:
                self.commands.append(MachOUUIDCommand(macho_file, cmd))
            elif cmd in [LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS]:
                self.commands.append(MachOVersionMinCommand(macho_file, cmd))
            elif cmd in [LC_UNIXTHREAD, LC_THREAD]:
                self.commands.append(MachOThreadCommand(macho_file, cmd))
            elif cmd == LC_MAIN:
                self.commands.append(MachOMainCommand(macho_file, cmd))
            elif cmd in [
                    LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB,
                    LC_ID_DYLIB
            ]:
                self.commands.append(MachOLoadDYLibCommand(macho_file, cmd))
            elif cmd in [
                    LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
                    LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS
            ]:
                self.commands.append(MachOLinkeditDataCommand(macho_file, cmd))
            elif cmd == LC_RPATH:
                self.commands.append(MachORPathCommand(macho_file, cmd))
            elif cmd == LC_SOURCE_VERSION:
                self.commands.append(MachOSourceVersionCommand(
                    macho_file, cmd))
            elif cmd == LC_ENCRYPTION_INFO:
                self.commands.append(
                    MachOEncryptionInfoCommand(macho_file, cmd))
            else:
                raise Exception(
                    "unknow load command : 0x%x - please report it!" % cmd)