def parse_load_dylib(self, lc): offset = get_int(self.f) timestamp = get_int(self.f) current_version = get_int(self.f) compatibility_version = get_int(self.f) if self.macho.is_little(): offset = little(offset, 'I') timestamp = little(timestamp, 'I') current_version = little(current_version, 'I') compatibility_version = little(compatibility_version, 'I') timestamp = datetime.fromtimestamp(timestamp) current_version = Version(version=current_version) compatibility_version = Version(version=compatibility_version) dylib = strip(self.f.read(lc.size - 24)) self.macho.add_dylib(dylib) lc.add_data('timestamp', str(timestamp)) lc.add_data('current_version', current_version.version) lc.add_data('compatibility_version', compatibility_version.version) lc.add_data('dylib', dylib) self.macho.add_lc(lc)
def parse_section(self): name = strip(self.f.read(16)) segname = strip(self.f.read(16)) addr = get_int(self.f) if self.macho.is_32_bit() else get_ll(self.f) size = get_int(self.f) if self.macho.is_32_bit() else get_ll(self.f) offset = get_int(self.f) align = get_int(self.f) reloff = get_int(self.f) nreloc = get_int(self.f) flags = get_int(self.f) self.f.read(8) if self.macho.is_32_bit() else self.f.read(12) if self.macho.is_little(): addr = little(addr, 'I') if self.macho.is_32_bit() \ else little(addr, 'Q') size = little(size, 'I') if self.macho.is_32_bit() \ else little(size, 'Q') offset = little(offset, 'I') align = little(align, 'I') reloff = little(reloff, 'I') nreloc = little(nreloc, 'I') flags = little(flags, 'I') section = Section(name=name, segname=segname, addr=addr, offset=offset, align=align, reloff=reloff, nreloc=nreloc, size=size) self.parse_section_flags(section, flags) return section
def parse_linkedit_data(self, lc): offset = get_int(self.f) size = get_int(self.f) if self.macho.is_little(): offset = little(offset, 'I') size = little(size, 'I') lc.add_data('offset', offset) lc.add_data('size', size) self.macho.add_lc(lc)
def parseMain(self, lc): offset = getLL(self._f) size = getLL(self._f) if self._macho.isLittle(): offset = little(offset, 'Q') size = little(size, 'Q') lc.addData('offset', offset) lc.addData('size', size) self._macho.addLC(lc)
def parse_main(self, lc): offset = get_ll(self.f) size = get_ll(self.f) if self.macho.is_little(): offset = little(offset, 'Q') size = little(size, 'Q') lc.add_data('offset', offset) lc.add_data('size', size) self.macho.add_lc(lc)
def parseLinkedITData(self, lc): offset = getInt(self._f) size = getInt(self._f) if self._macho.isLittle(): offset = little(offset, 'I') size = little(size, 'I') lc.addData('offset', offset) lc.addData('size', size) self._macho.addLC(lc)
def parseTwoLevelHints(self, lc): offset = getInt(self._f) nhints = getInt(self._f) if self._macho.isLittle(): offset = little(offset, 'I') nhints = little(nhints, 'I') lc.addData('offset', offset) lc.addData('nhints', nhints) self._macho.addLC(lc)
def parse_twolevel_hints(self, lc): offset = get_int(self.f) nhints = get_int(self.f) if self.macho.is_little(): offset = little(offset, 'I') nhints = little(nhints, 'I') lc.add_data('offset', offset) lc.add_data('nhints', nhints) self.macho.add_lc(lc)
def parse_version_min_os(self, lc): version = get_int(self.f) sdk = get_int(self.f) if self.macho.is_little(): version = little(version, 'I') sdk = little(sdk, 'I') version = Version(version=version) sdk = Version(version=sdk) lc.add_data('version', version.version) lc.add_data('sdk', sdk.version) self.macho.minos = version self.macho.add_lc(lc)
def parsePrebindCksum(self, lc): cksum = getInt(self._f) if self._macho.isLittle(): cksum = little(cksum, 'I') lc.addData('cksum', cksum) self._macho.addLC(lc)
def parse_prebind_cksum(self, lc): cksum = get_int(self.f) if self.macho.is_little(): cksum = little(cksum, 'I') lc.add_data('cksum', cksum) self.macho.add_lc(lc)
def parseEncryptionInfo(self, lc): offset = getInt(self._f) size = getInt(self._f) id = getInt(self._f) if self._macho.isLittle(): offset = little(offset, 'I') size = little(size, 'I') id = little(id, 'I') lc.addData('offset', offset) lc.addData('size', size) lc.addData('id', id) if lc.getCmd() == 'ENCRYPTION_INFO_64': # Skip padding self._f.read(4) self._macho.addLC(lc)
def parse_encryption_info(self, lc): offset = get_int(self.f) size = get_int(self.f) id = get_int(self.f) if self.macho.is_little(): offset = little(offset, 'I') size = little(size, 'I') id = little(id, 'I') lc.add_data('offset', offset) lc.add_data('size', size) lc.add_data('id', id) if lc.cmd == 'ENCRYPTION_INFO_64': # Skip padding self.f.read(4) self.macho.add_lc(lc)
def parse_uuid(self, lc): uuid = self.f.read(16) if self.macho.is_little(): uuid = UUID(bytes=little(uuid, '16s')) else: uuid = UUID(bytes=uuid) lc.add_data('uuid', uuid.hex) self.macho.add_lc(lc)
def parse_routines(self, lc): if lc.cmd == 'ROUTINES': init_address = get_int(self.f) init_module = get_int(self.f) if self.macho.is_little(): init_address = little(init_address, 'I') init_module = little(init_module, 'I') self.f.read(24) else: init_address = get_ll(self.f) init_module = get_ll(self.f) if self.macho.is_little(): init_address = little(init_address, 'Q') init_module = little(init_module, 'Q') self.f.read(48) lc.add_data('init_address', init_address) lc.add_data('init_module', init_module) self.macho.add_lc(lc)
def parseRoutines(self, lc): if lc.getCmd() == 'ROUTINES': init_address = getInt(self._f) init_module = getInt(self._f) if self._macho.isLittle(): init_address = little(init_address, 'I') init_module = little(init_module, 'I') self._f.read(24) else: init_address = getLL(self._f) init_module = getLL(self._f) if self._macho.isLittle(): init_address = little(init_address, 'Q') init_module = little(init_module, 'Q') self._f.read(48) lc.addData('init_address', init_address) lc.addData('init_module', init_module) self._macho.addLC(lc)
def parseUUID(self, lc): uuid = self._f.read(16) if self._macho.isLittle(): uuid = UUID(bytes=little(uuid, '16s')) else: uuid = UUID(bytes=uuid) lc.addData('uuid', uuid.hex) self._macho.addLC(lc)
def parse_thread(self, lc): state = get_int(self.f) count = get_int(self.f) self.f.read(lc.size - 16) if self.macho.is_little(): state = little(state, 'I') count = little(count, 'I') try: state = dictionary.thread_states[state] except: data = {'offset': self.f.tell() - lc.size, 'state': state} a = Abnormality(title='INVALID THREAD STATE FLAVOR', data=data) self.add_abnormality(a) lc.add_data('state', state) lc.add_data('count', count) self.macho.add_lc(lc)
def parseThread(self, lc): state = getInt(self._f) count = getInt(self._f) self._f.read(lc.getSize() - 16) if self._macho.isLittle(): state = little(state, 'I') count = little(count, 'I') try: state = dictionary.thread_states[state] except: data = {'offset': self._f.tell() - lc.getSize(), 'state': state} a = Abnormality(title='INVALID THREAD STATE FLAVOR', data=data) self.addAbnormality(a) lc.addData('state', state) lc.addData('count', count) self._macho.addLC(lc)
def parse_symtab(self, lc): symoff = get_int(self.f) nsyms = get_int(self.f) stroff = get_int(self.f) strsize = get_int(self.f) if self.macho.is_little(): symoff = little(symoff, 'I') nsyms = little(nsyms, 'I') stroff = little(stroff, 'I') strsize = little(strsize, 'I') self.macho.symtab = SymbolTable(offset=symoff, nsyms=nsyms) self.macho.strtab = StringTable(offset=stroff, size=strsize) lc.add_data('symoff', symoff) lc.add_data('nsyms', nsyms) lc.add_data('stroff', stroff) lc.add_data('strsize', strsize) self.macho.add_lc(lc)
def parseDySymTab(self, lc): il = getInt(self._f) nl = getInt(self._f) ie = getInt(self._f) ne = getInt(self._f) iu = getInt(self._f) nu = getInt(self._f) self._f.read(lc.getSize() - 32) if self._macho.isLittle(): il = little(il, 'I') nl = little(nl, 'I') ie = little(ie, 'I') ne = little(ne, 'I') iu = little(iu, 'I') nu = little(nu, 'I') self._macho.getSymTab().setIL(il) self._macho.getSymTab().setNL(nl) self._macho.getSymTab().setIE(ie) self._macho.getSymTab().setNE(ne) self._macho.getSymTab().setIU(iu) self._macho.getSymTab().setNU(nu) lc.addData('il', il) lc.addData('nl', nl) lc.addData('ie', ie) lc.addData('ne', ne) lc.addData('iu', iu) lc.addData('nu', nu) self._macho.addLC(lc)
def parse_dysymtab(self, lc): il = get_int(self.f) nl = get_int(self.f) ie = get_int(self.f) ne = get_int(self.f) iu = get_int(self.f) nu = get_int(self.f) self.f.read(lc.size - 32) if self.macho.is_little(): self.macho.symtab.il = little(il, 'I') self.macho.symtab.nl = little(nl, 'I') self.macho.symtab.ie = little(ie, 'I') self.macho.symtab.ne = little(ne, 'I') self.macho.symtab.iu = little(iu, 'I') self.macho.symtab.nu = little(nu, 'I') lc.add_data('il', il) lc.add_data('nl', nl) lc.add_data('ie', ie) lc.add_data('ne', ne) lc.add_data('iu', iu) lc.add_data('nu', nu) self.macho.add_lc(lc)
def parse_prebound_dylib(self, lc): dylib = readstring(self.f) nmodules = get_int(self.f) linked_modules = readstring(self.f) if self.macho.is_little(): nmodules = little(nmodules, 'I') lc.add_data('dylib', dylib) lc.add_data('nmodules', nmodules) lc.add_data('linked_modules', linked_modules) self.macho.add_lc(lc)
def parseThread(self, lc): state = getInt(self._f) count = getInt(self._f) self._f.read(lc.getSize() - 16) if self._macho.isLittle(): state = little(state, 'I') count = little(count, 'I') try: state = dictionary.thread_states[state] except: data = { 'offset': self._f.tell() - lc.getSize(), 'state': state } a = Abnormality(title='INVALID THREAD STATE FLAVOR', data=data) self.addAbnormality(a) lc.addData('state', state) lc.addData('count', count) self._macho.addLC(lc)
def parseLoadDylib(self, lc): offset = getInt(self._f) if self._macho.isLittle(): offset = little(offset, 'I') # skip to dylib self._f.read(offset - 12) dylib = strip(self._f.read(lc.getSize() - 24)) self._macho.addDylib(dylib) lc.addData('dylib', dylib) self._macho.addLC(lc)
def parse_load_dylib(self, lc): offset = get_int(self.f) if self.macho.is_little(): offset = little(offset, 'I') # skip to dylib self.f.read(offset - 12) dylib = strip(self.f.read(lc.size - 24)) self.macho.add_dylib(dylib) lc.add_data('dylib', dylib) self.macho.add_lc(lc)
def parse_version_min_os(self, lc): version = get_int(self.f) sdk = get_int(self.f) if self.macho.is_little(): version = little(version, 'I') sdk = little(sdk, 'I') vx = version >> 16 vy = (version >> 8) & 0xff vz = version & 0xff version = OSVersion(vx=vx, vy=vy, vz=vz) sx = str(sdk >> 16) sy = str((sdk >> 8) & 0xff) sz = str(sdk & 0xff) sdk = sx + '.' + sy + '.' + sz lc.add_data('version', version.version) lc.add_data('sdk', sdk) self.macho.minos = version self.macho.add_lc(lc)
def parseVersionMinOS(self, lc): version = getInt(self._f) sdk = getInt(self._f) if self._macho.isLittle(): version = little(version, 'I') sdk = little(sdk, 'I') vx = version >> 16 vy = (version >> 8) & 0xff vz = version & 0xff version = OSVersion(vx=vx, vy=vy, vz=vz) sx = str(sdk >> 16) sy = str((sdk >> 8) & 0xff) sz = str(sdk & 0xff) sdk = sx + '.' + sy + '.' + sz lc.addData('version', version.getVersion()) lc.addData('sdk', sdk) self._macho.setMinOS(version) self._macho.addLC(lc)
def parse_thread(self, lc): state = get_int(self.f) count = get_int(self.f) self.f.read(lc.size - 16) if self.macho.is_little(): state = little(state, 'I') count = little(count, 'I') try: state = dictionary.thread_states[state] except: data = { 'offset': self.f.tell() - lc.size, 'state': state } a = Abnormality(title='INVALID THREAD STATE FLAVOR', data=data) self.add_abnormality(a) lc.add_data('state', state) lc.add_data('count', count) self.macho.add_lc(lc)
def parse_dyld_info(self, lc): rebase_off = get_int(self.f) rebase_size = get_int(self.f) bind_off = get_int(self.f) bind_size = get_int(self.f) weak_bind_off = get_int(self.f) weak_bind_size = get_int(self.f) lazy_bind_off = get_int(self.f) lazy_bind_size = get_int(self.f) export_off = get_int(self.f) export_size = get_int(self.f) if self.macho.is_little(): rebase_off = little(rebase_off, 'I') rebase_size = little(rebase_size, 'I') bind_off = little(bind_off, 'I') bind_size = little(bind_size, 'I') weak_bind_off = little(weak_bind_off, 'I') weak_bind_size = little(weak_bind_size, 'I') lazy_bind_off = little(lazy_bind_off, 'I') lazy_bind_size = little(lazy_bind_size, 'I') export_off = little(export_off, 'I') export_size = little(export_size, 'I') lc.add_data('rebase_off', rebase_off) lc.add_data('rebase_size', rebase_size) lc.add_data('bind_off', bind_off) lc.add_data('bind_size', bind_size) lc.add_data('weak_bind_off', weak_bind_off) lc.add_data('weak_bind_size', weak_bind_size) lc.add_data('lazy_bind_off', lazy_bind_off) lc.add_data('lazy_bind_size', lazy_bind_size) lc.add_data('export_off', export_off) lc.add_data('export_size', export_size) self.macho.add_lc(lc)
def parseDyldInfo(self, lc): rebase_off = getInt(self._f) rebase_size = getInt(self._f) bind_off = getInt(self._f) bind_size = getInt(self._f) weak_bind_off = getInt(self._f) weak_bind_size = getInt(self._f) lazy_bind_off = getInt(self._f) lazy_bind_size = getInt(self._f) export_off = getInt(self._f) export_size = getInt(self._f) if self._macho.isLittle(): rebase_off = little(rebase_off, 'I') rebase_size = little(rebase_size, 'I') bind_off = little(bind_off, 'I') bind_size = little(bind_size, 'I') weak_bind_off = little(weak_bind_off, 'I') weak_bind_size = little(weak_bind_size, 'I') lazy_bind_off = little(lazy_bind_off, 'I') lazy_bind_size = little(lazy_bind_size, 'I') export_off = little(export_off, 'I') export_size = little(export_size, 'I') lc.addData('rebase_off', rebase_off) lc.addData('rebase_size', rebase_size) lc.addData('bind_off', bind_off) lc.addData('bind_size', bind_size) lc.addData('weak_bind_off', weak_bind_off) lc.addData('weak_bind_size', weak_bind_size) lc.addData('lazy_bind_off', lazy_bind_off) lc.addData('lazy_bind_size', lazy_bind_size) lc.addData('export_off', export_off) lc.addData('export_size', export_size) self._macho.addLC(lc)
def parseSymTab(self, lc): symoff = getInt(self._f) nsyms = getInt(self._f) stroff = getInt(self._f) strsize = getInt(self._f) if self._macho.isLittle(): symoff = little(symoff, 'I') nsyms = little(nsyms, 'I') stroff = little(stroff, 'I') strsize = little(strsize, 'I') symtab = SymbolTable(offset=symoff, nsyms=nsyms) strtab = StringTable(offset=stroff, size=strsize) self._macho.setSymTab(symtab) self._macho.setStrTab(strtab) lc.addData('symoff', symoff) lc.addData('nsyms', nsyms) lc.addData('stroff', stroff) lc.addData('strsize', strsize) self._macho.addLC(lc)
def parseLinkerOption(self, lc): count = getInt(self._f) if self._macho.isLittle(): count = little(count, 'I') linker_options = [] start = self._f.tell() for i in range(count): linker_option = readstring(self._f) linker_options.append(linker_option) length = self._f.tell() - start self._f.read(lc.getSize() - length - 12) lc.addData('count', count) lc.addData('linker_options', linker_options) self._macho.addLC(lc)
def parse_linker_option(self, lc): count = get_int(self.f) if self.macho.is_little(): count = little(count, 'I') linker_options = [] start = self.f.tell() for i in range(count): linker_option = readstring(self.f) linker_options.append(linker_option) length = self.f.tell() - start self.f.read(lc.size - length - 12) lc.add_data('count', count) lc.add_data('linker_options', linker_options) self.macho.add_lc(lc)
def parse_source_version(self, lc): version = get_ll(self.f) if self.macho.is_little(): version = little(version, 'Q') a = str((version >> 40) & 0xffffff) b = str((version >> 30) & 0x3ff) c = str((version >> 20) & 0x3ff) d = str((version >> 10) & 0x3ff) e = str(version & 0x3ff) # TODO: fix source version. version = a + '.' + b + '.' + c + '.' + d + '.' + e lc.add_data('version', version) self.macho.add_lc(lc)