def _recursiveProcessExportTrieNode(f, start, cur, end, prefix, symbols): if cur < end: f.seek(cur) termSize = f.read_byte() if termSize: sym = prefix readULeb128(f) addr = readULeb128(f) symbols.append(Symbol(sym, addr, SYMTYPE_GENERIC, extern=True)) f.seek(cur + termSize + 1) childCount = f.read_byte() for i in range(childCount): suffix = readString(f) offset = readULeb128(f) lastPos = f.tell() _recursiveProcessExportTrieNode(f, start, start + offset, end, prefix + suffix, symbols) f.seek(lastPos)
def _recursiveProcessExportTrieNode(f, start, cur, end, prefix, symbols, macho): if cur < end: f.seek(cur) termSize = f.read_byte() if termSize: sym = prefix readULeb128(f) file_addr = readULeb128(f) vm_addr = macho.mappings.toVM(file_addr) symbols.append(Symbol(sym, vm_addr, SYMTYPE_GENERIC, extern=True)) f.seek(cur + termSize + 1) childCount = f.read_byte() for i in range(childCount): suffix = readString(f) offset = readULeb128(f) lastPos = f.tell() _recursiveProcessExportTrieNode(f, start, start + offset, end, prefix + suffix, symbols, macho) f.seek(lastPos)
def _stringReader(file, curAddr, final): while curAddr < final: (string, length) = readString(file, returnLength=True) if length: yield Symbol(string, curAddr, SYMTYPE_CSTRING) curAddr += length+1
def _bind(machO, size, symbols): libord = 0 sym = None addr = 0 f = machO.file end = f.tell() + size lcs_all = machO.loadCommands.all ptrwidth = machO.pointerWidth allSegs = lcs_all('className', 'SegmentCommand') while f.tell() < end: c = f.read_byte() imm = c & 0xf # BIND_IMMEDIATE_MASK opcode = c & 0xf0 # BIND_OPCODE_MASK if opcode == 0: # BIND_OPCODE_DONE pass elif opcode == 0x10: # BIND_OPCODE_SET_DYLIB_ORDINAL_IMM libord = imm elif opcode == 0x20: # BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB libord = readULeb128(f) elif opcode == 0x30: # BIND_OPCODE_SET_DYLIB_SPECIAL_IMM libord = (imm | 0xf0) if imm else 0 elif opcode == 0x40: # BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM sym = readString(f) elif opcode == 0x50: # BIND_OPCODE_SET_TYPE_IMM pass elif opcode == 0x60: # BIND_OPCODE_SET_ADDEND_SLEB readSLeb128(f) elif opcode == 0x70: # BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB addr = allSegs[imm].vmaddr + readULeb128(f) elif opcode == 0x80: # BIND_OPCODE_ADD_ADDR_ULEB addr += readULeb128(f) elif opcode == 0x90: # BIND_OPCODE_DO_BIND symbols.append(Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += ptrwidth elif opcode == 0xa0: # BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB symbols.append(Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += ptrwidth + readULeb128(f) elif opcode == 0xb0: # BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED symbols.append(Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += (imm+1) * ptrwidth elif opcode == 0xc0: # BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB count = readULeb128(f) skip = readULeb128(f) for i in range(count): symbols.append(Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += skip + ptrwidth
def _bind(machO, size, symbols): libord = 0 sym = None addr = 0 f = machO.file end = f.tell() + size lcs_all = machO.loadCommands.all ptrwidth = machO.pointerWidth allSegs = lcs_all('className', 'SegmentCommand') while f.tell() < end: c = f.read_byte() imm = c & 0xf # BIND_IMMEDIATE_MASK opcode = c & 0xf0 # BIND_OPCODE_MASK addr = addr & (0xffffffffffffffff if machO.is64bit else 0xffffffff ) # FIXME: how about 64-bit? if opcode == 0: # BIND_OPCODE_DONE pass elif opcode == 0x10: # BIND_OPCODE_SET_DYLIB_ORDINAL_IMM libord = imm elif opcode == 0x20: # BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB libord = readULeb128(f) elif opcode == 0x30: # BIND_OPCODE_SET_DYLIB_SPECIAL_IMM libord = (imm | 0xf0) if imm else 0 elif opcode == 0x40: # BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM sym = readString(f) elif opcode == 0x50: # BIND_OPCODE_SET_TYPE_IMM pass elif opcode == 0x60: # BIND_OPCODE_SET_ADDEND_SLEB readSLeb128(f) elif opcode == 0x70: # BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB addr = allSegs[imm].vmaddr + readULeb128(f) elif opcode == 0x80: # BIND_OPCODE_ADD_ADDR_ULEB addr += readULeb128(f) elif opcode == 0x90: # BIND_OPCODE_DO_BIND symbols.append(Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += ptrwidth elif opcode == 0xa0: # BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB symbols.append(Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += ptrwidth + readULeb128(f) elif opcode == 0xb0: # BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED symbols.append(Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += (imm + 1) * ptrwidth elif opcode == 0xc0: # BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB count = readULeb128(f) skip = readULeb128(f) for i in range(count): symbols.append( Symbol(sym, addr, SYMTYPE_UNDEFINED, libord=libord)) addr += skip + ptrwidth
def _stringReader(file, curAddr, final): while curAddr < final: (string, length) = readString(file, returnLength=True) if length: yield Symbol(string, curAddr, SYMTYPE_CSTRING) curAddr += length + 1