Source code for vstruct.defs.macho.loader
import vstruct
from vstruct.primitives import *
from vstruct.defs.macho.const import *
vm_prot_t = v_uint32
cpu_type_t = v_uint32
cpu_subtype_t = v_uint32
lc_str = v_uint32
[docs]class load_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # type of load command
self.cmdsize = v_uint32() # total size of command in bytes
[docs]class segment_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SEGMENT
self.cmdsize = v_uint32() # includes sizeof section structs
self.segname = v_str(size=16) # segment name
self.vmaddr = v_uint32() # memory address of this segment
self.vmsize = v_uint32() # memory size of this segment
self.fileoff = v_uint32() # file offset of this segment
self.filesize = v_uint32() # amount to map from the file
self.maxprot = vm_prot_t() # maximum VM protection
self.initprot = vm_prot_t() # initial VM protection
self.nsects = v_uint32() # number of sections in segment
self.flags = v_uint32() # flags
[docs]class segment_command_64(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SEGMENT_64
self.cmdsize = v_uint32() # includes sizeof section_64 structs
self.segname[16] = v_uint8() # segment name
self.vmaddr = v_uint64() # memory address of this segment
self.vmsize = v_uint64() # memory size of this segment
self.fileoff = v_uint64() # file offset of this segment
self.filesize = v_uint64() # amount to map from the file
self.maxprot = vm_prot_t() # maximum VM protection
self.initprot = vm_prot_t() # initial VM protection
self.nsects = v_uint32() # number of sections in segment
self.flags = v_uint32() # flags
[docs]class section(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.sectname = v_str(size=16) # name of this section
self.segname = v_str(size=16) # segment this section goes in
self.addr = v_uint32() # memory address of this section
self.size = v_uint32() # size in bytes of this section
self.offset = v_uint32() # file offset of this section
self.align = v_uint32() # section alignment (power of 2)
self.reloff = v_uint32() # file offset of relocation entries
self.nreloc = v_uint32() # number of relocation entries
self.flags = v_uint32() # flags (section type and attributes)
self.reserved1 = v_uint32() # reserved (for offset or index)
self.reserved2 = v_uint32() # reserved (for count or sizeof)
[docs]class section_64(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.sectname = v_str(size=16) # name of this section
self.segname = v_str(size=16) # segment this section goes in
self.addr = v_uint64() # memory address of this section
self.size = v_uint64() # size in bytes of this section
self.offset = v_uint32() # file offset of this section
self.align = v_uint32() # section alignment (power of 2)
self.reloff = v_uint32() # file offset of relocation entries
self.nreloc = v_uint32() # number of relocation entries
self.flags = v_uint32() # flags (section type and attributes)
self.reserved1 = v_uint32() # reserved (for offset or index)
self.reserved2 = v_uint32() # reserved (for count or sizeof)
self.reserved3 = v_uint32() # reserved
[docs]class fvmlib_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_IDFVMLIB or LC_LOADFVMLIB
self.cmdsize = v_uint32() # includes pathname string
self.name = lc_str() # library's target pathname
self.minor_version = v_uint32() # library's minor version number
self.header_addr = v_uint32() # library's header address
[docs]class dylib_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, LC_REEXPORT_DYLIB
self.cmdsize = v_uint32() # includes pathname string
self.name = lc_str() # library's path name
self.timestamp = v_uint32() # library's build time stamp
self.current_version = v_uint32() # library's current version number
self.compatibility_version = v_uint32() # library's compatibility vers number
self.namedata = v_bytes(size=0)
[docs] def vsParse(self, bytes, offset=0):
# So we can grab the name data
retoff = vstruct.VStruct.vsParse(self, bytes, offset=offset)
# Grab the name from the inline data...
name = bytes[ offset + self.name : offset + self.cmdsize ]
self.namedata = name.split('\x00', 1)[0]
return retoff
[docs]class sub_framework_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SUB_FRAMEWORK
self.cmdsize = v_uint32() # includes umbrella string
self.umbrella = lc_str() # the umbrella framework name
[docs]class sub_client_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SUB_CLIENT
self.cmdsize = v_uint32() # includes client string
self.client = lc_str() # the client name
[docs]class sub_umbrella_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SUB_UMBRELLA
self.cmdsize = v_uint32() # includes sub_umbrella string
self.sub_umbrella = lc_str() # the sub_umbrella framework name
[docs]class sub_library_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SUB_LIBRARY
self.cmdsize = v_uint32() # includes sub_library string
self.sub_library = lc_str() # the sub_library name
[docs]class prebound_dylib_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_PREBOUND_DYLIB
self.cmdsize = v_uint32() # includes strings
self.name = lc_str() # library's path name
self.nmodules = v_uint32() # number of modules in library
self.linked_modules = lc_str() # bit vector of linked modules
[docs]class dylinker_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_ID_DYLINKER or LC_LOAD_DYLINKER
self.cmdsize = v_uint32() # includes pathname string
self.name = lc_str() # dynamic linker's path name
[docs]class thread_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_THREAD or LC_UNIXTHREAD
self.cmdsize = v_uint32() # total size of this command
[docs]class routines_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_ROUTINES
self.cmdsize = v_uint32() # total size of this command
self.init_address = v_uint32() # address of initialization routine
self.init_module = v_uint32() # index into the module table that
self.reserved1 = v_uint32()
self.reserved2 = v_uint32()
self.reserved3 = v_uint32()
self.reserved4 = v_uint32()
self.reserved5 = v_uint32()
self.reserved6 = v_uint32()
[docs]class routines_command_64(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_ROUTINES_64
self.cmdsize = v_uint32() # total size of this command
self.init_address = v_uint64() # address of initialization routine
self.init_module = v_uint64() # index into the module table that
self.reserved1 = v_uint64()
self.reserved2 = v_uint64()
self.reserved3 = v_uint64()
self.reserved4 = v_uint64()
self.reserved5 = v_uint64()
self.reserved6 = v_uint64()
[docs]class symtab_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SYMTAB
self.cmdsize = v_uint32() # sizeof(struct symtab_command)
self.symoff = v_uint32() # symbol table offset
self.nsyms = v_uint32() # number of symbol table entries
self.stroff = v_uint32() # string table offset
self.strsize = v_uint32() # string table size in bytes
[docs]class dysymtab_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_DYSYMTAB
self.cmdsize = v_uint32() # sizeof(struct dysymtab_command)
self.ilocalsym = v_uint32() # index to local symbols
self.nlocalsym = v_uint32() # number of local symbols
self.iextdefsym = v_uint32() # index to externally defined symbols
self.nextdefsym = v_uint32() # number of externally defined symbols
self.iundefsym = v_uint32() # index to undefined symbols
self.nundefsym = v_uint32() # number of undefined symbols
self.tocoff = v_uint32() # file offset to table of contents
self.ntoc = v_uint32() # number of entries in table of contents
self.modtaboff = v_uint32() # file offset to module table
self.nmodtab = v_uint32() # number of module table entries
self.extrefsymoff = v_uint32() # offset to referenced symbol table
self.nextrefsyms = v_uint32() # number of referenced symbol table entries
self.indirectsymoff = v_uint32() # file offset to the indirect symbol table
self.nindirectsyms = v_uint32() # number of indirect symbol table entries
self.extreloff = v_uint32() # offset to external relocation entries
self.nextrel = v_uint32() # number of external relocation entries
self.locreloff = v_uint32() # offset to local relocation entries
self.nlocrel = v_uint32() # number of local relocation entries
[docs]class dylib_table_of_contents(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.symbol_index = v_uint32() # the defined external symbol (index into the symbol table)
self.module_index = v_uint32() # index into the module table this symbol is defined in
[docs]class dylib_module(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.module_name = v_uint32() # the module name (index into string table)
self.iextdefsym = v_uint32() # index into externally defined symbols
self.nextdefsym = v_uint32() # number of externally defined symbols
self.irefsym = v_uint32() # index into reference symbol table
self.nrefsym = v_uint32() # number of reference symbol table entries
self.ilocalsym = v_uint32() # index into symbols for local symbols
self.nlocalsym = v_uint32() # number of local symbols
self.iextrel = v_uint32() # index into external relocation entries
self.nextrel = v_uint32() # number of external relocation entries
self.iinit_iterm = v_uint32() # low 16 bits are the index into the init section, high 16 bits are the index into the term section
self.ninit_nterm = v_uint32() # low 16 bits are the number of init section entries, high 16 bits are the number of term section entries
self.objc_module_info_addr = v_uint32() # the (__OBJC,__module_info) section
self.objc_module_info_size = v_uint32() # the (__OBJC,__module_info) section
[docs]class dylib_module_64(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.module_name = v_uint32() # the module name (index into string table)
self.iextdefsym = v_uint32() # index into externally defined symbols
self.nextdefsym = v_uint32() # number of externally defined symbols
self.irefsym = v_uint32() # index into reference symbol table
self.nrefsym = v_uint32() # number of reference symbol table entries
self.ilocalsym = v_uint32() # index into symbols for local symbols
self.nlocalsym = v_uint32() # number of local symbols
self.iextrel = v_uint32() # index into external relocation entries
self.nextrel = v_uint32() # number of external relocation entries
self.iinit_iterm = v_uint32() # low 16 bits are the index into the init section, high 16 bits are the index into the term section
self.ninit_nterm = v_uint32() # low 16 bits are the number of init section entries, high 16 bits are the number of term section entries
self.objc_module_info_size = v_uint32() # the (__OBJC,__module_info) section
self.objc_module_info_addr = v_uint64() # the (__OBJC,__module_info) section
[docs]class dylib_reference(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.flags = v_uint32() # flags to indicate the type of reference
[docs]class twolevel_hints_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_TWOLEVEL_HINTS
self.cmdsize = v_uint32() # sizeof(struct twolevel_hints_command)
self.offset = v_uint32() # offset to the hint table
self.nhints = v_uint32() # number of hints in the hint table
[docs]class twolevel_hint(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.itoc = v_uint32() # index into the table of contents
[docs]class prebind_cksum_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_PREBIND_CKSUM
self.cmdsize = v_uint32() # sizeof(struct prebind_cksum_command)
self.cksum = v_uint32() # the check sum or zero
[docs]class uuid_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_UUID
self.cmdsize = v_uint32() # sizeof(struct uuid_command)
self.uuid[16] = v_uint8() # the 128-bit uuid
[docs]class rpath_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_RPATH
self.cmdsize = v_uint32() # includes string
self.path = lc_str() # path to add to run path
[docs]class linkedit_data_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_CODE_SIGNATURE or LC_SEGMENT_SPLIT_INFO
self.cmdsize = v_uint32() # sizeof(struct linkedit_data_command)
self.dataoff = v_uint32() # file offset of data in __LINKEDIT segment
self.datasize = v_uint32() # file size of data in __LINKEDIT segment
[docs]class encryption_info_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_ENCRYPTION_INFO
self.cmdsize = v_uint32() # sizeof(struct encryption_info_command)
self.cryptoff = v_uint32() # file offset of encrypted range
self.cryptsize = v_uint32() # file size of encrypted range
self.cryptid = v_uint32() # which enryption system, 0 means not-encrypted yet
[docs]class symseg_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_SYMSEG
self.cmdsize = v_uint32() # sizeof(struct symseg_command)
self.offset = v_uint32() # symbol segment offset
self.size = v_uint32() # symbol segment size in bytes
[docs]class ident_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_IDENT
self.cmdsize = v_uint32() # strings that follow this command
[docs]class fvmfile_command(vstruct.VStruct):
def __init__(self):
vstruct.VStruct.__init__(self)
self.cmd = v_uint32() # LC_FVMFILE
self.cmdsize = v_uint32() # includes pathname string
self.name = lc_str() # files pathname
self.header_addr = v_uint32() # files virtual address
command_classes = {
LC_SEGMENT: segment_command,
LC_SYMTAB: symtab_command,
LC_LOAD_DYLIB: dylib_command,
}
[docs]def getCommandClass(cmdtype):
cls = command_classes.get(cmdtype)
if cls != None:
return cls
return load_command