def FromElf(params): ''' ioc, create ApplicationBinary instance from file .elf ''' # open a stream file = open(params['path'], "rb") elf = elffile.ELFFile(file) # set attributes instance = BinaryApplication() instance._MemoryAddress = params['addr_mem'] instance._BaseAddress = params['addr_base'] instance._HeaderAddress = params['addr_header'] instance._EntryAddress = elf.header.e_entry data = bytearray(0) segments = [i for i in elf.iter_segments()] # calculate lowest address lowest = None for segment in segments: if (lowest is None): lowest = segment.header.p_vaddr if (lowest > segment.header.p_vaddr): lowest = segment.header.p_vaddr # calculate segment for segment in segments: position = segment.header.p_vaddr - lowest size = segment.header.p_memsz # resize data buffer resize = (position + size) - (len(data)) if (resize > 0): data.extend([0] * resize) data[position:position + size] = segment.data() instance._binaryData = data file.close() return instance
def sections(self, args, file, opts): output = [] with open(file.file_path, 'rb') as f: try: for section in elffile.ELFFile(f).iter_sections(): s = {} # pylint: disable=invalid-name if section.name == '': s['name'] = '-' else: s['name'] = str(section.name) s['address'] = str(hex(section['sh_addr'])) s['size'] = str(hex(section['sh_size'])) s['offset'] = str(hex(section['sh_offset'])) s['type'] = str(section['sh_type'])[4:] if str(descriptions.describe_sh_flags( section['sh_flags'])) == '': s['flags'] = '-' else: s['flags'] = str( descriptions.describe_sh_flags( section['sh_flags'])) output += [s] except exceptions.ELFError as err: raise error.CommandError(str(err)) return output
def scan(self, binaries): """ Scan the provided binaries for symbol information. The first binary in the list provides the symbols, and the remaining binaries are used to fill in missing information for that set of symbols. """ main_binary = elffile.ELFFile(open(binaries[0], 'rb')) symbols = {} print("[INFO] collecting symbols...") self.scan_symtab(symbols, main_binary) if not main_binary.has_dwarf_info(): return debug_info = main_binary.get_dwarf_info() print("[INFO] analyzing debug info...") self.scan_debuginfo(symbols, main_binary, debug_info) print("[INFO] removing unneeded sections...") self.remove_unneeded_sections(symbols) print("[INFO] resolving unknown symbols...") self.resolve_unknowns(symbols, main_binary, debug_info) return symbols
def load_symbols(fname): print "loading %s" % fname fd = open(fname, "rb") elf = elffile.ELFFile(fd) symbols = {} dynsym = elf.get_section_by_name(".dynsym") for symbol in dynsym.iter_symbols(): if symbol.name != "" and "$" not in symbol.name: symbols[symbol.name] = symbol.entry["st_value"] #Load plt entries rela_plt = elf.get_section_by_name(".rela.plt") plt_entries = {} for rel in rela_plt.iter_relocations(): offset = rel.entry["r_offset"] name = dynsym.get_symbol(rel.entry["r_info_sym"]).name plt_entries[offset] = name #Find code for plt entries plt = elf.get_section_by_name(".plt") plt_base = plt.header["sh_addr"] md = cs.Cs(cs.CS_ARCH_ARM64, cs.CS_MODE_ARM) asm = list(md.disasm(plt.data(), plt_base)) for i in xrange(len(asm)): if asm[i].mnemonic == "adrp" and asm[i + 2].mnemonic == "add": plt_entry = int(asm[i].op_str.split("#")[-1], 0) + int( asm[i + 2].op_str.split("#")[-1], 0) if plt_entry in plt_entries: symbol_name = plt_entries[plt_entry] symbols[symbol_name] = plt_base + (i * 4) return symbols
def parseElf(inFile): m = {} m["romsize"] = 0 m["ramsize"] = 0 romsections = [".rodata", ".vectors"] ramsections = [".data", ".bss", ".init_array", ".shbss", ".sbss"] heapStart = None with open(inFile, "rb") as f: e = elffile.ELFFile(f) for s in e.iter_sections(): if s.name.startswith(".text"): m["romsize"] += s.data_size elif s.name.startswith(".srodata"): m["romsize"] += s.data_size elif s.name.startswith(".sdata"): m["ramsize"] += s.data_size elif any(n in s.name for n in romsections): m["romsize"] += s.data_size elif any(n in s.name for n in ramsections): m["ramsize"] += s.data_size elif s.name.startswith(".gcc_except"): pass elif s.name.startswith(".sdata2"): pass elif isinstance(s, SymbolTableSection): for sym in s.iter_symbols(): if sym.name == "_heap_start": heapStart = sym["st_value"] else: print("ignored: " + s.name) return m, heapStart
def __setstate__(self, data): self.__dict__.update(data) self.binary_stream = open(self.binary, 'rb') self.reader = elffile.ELFFile(self.binary_stream) if self._dynamic and 'DT_STRTAB' in self._dynamic: fakestrtabheader = {'sh_offset': self._dynamic['DT_STRTAB']} self.strtab = elffile.StringTableSection(fakestrtabheader, 'strtab_cle', self.memory) if 'DT_SYMTAB' in self._dynamic and 'DT_SYMENT' in self._dynamic: fakesymtabheader = { 'sh_offset': self._dynamic['DT_SYMTAB'], 'sh_entsize': self._dynamic['DT_SYMENT'], 'sh_size': 0 } # bogus size: no iteration allowed self.dynsym = elffile.SymbolTableSection( fakesymtabheader, 'symtab_cle', self.memory, self.reader, self.strtab) if 'DT_GNU_HASH' in self._dynamic: self.hashtable = GNUHashTable(self.dynsym, self.memory, self._dynamic['DT_GNU_HASH'], self.arch) elif 'DT_HASH' in self._dynamic: self.hashtable = ELFHashTable(self.dynsym, self.memory, self._dynamic['DT_HASH'], self.arch)
def read(path): """Read a vmlinux file and extract some info from it. Update the build document in place. Info extracted: 0. Size of the .text section. 1. Size of the .data section. 2. Size of the .bss section. :param path: The path to the vmlinux file. :type path: str :return A dictionary with the extracted values. """ extracted = {} if os.path.isfile(path): with io.open(path, mode="rb") as vmlinux_strm: elf_file = elffile.ELFFile(vmlinux_strm) for elf_sect in DEFAULT_ELF_SECTIONS: sect = elf_file.get_section_by_name(elf_sect[0]) if sect: extracted[elf_sect[1]] = sect["sh_size"] data_sect = elf_file.get_section_by_name(".data") if data_sect: extracted["vmlinux_data_size"] = data_sect["sh_size"] else: extracted["vmlinux_data_size"] = \ calculate_data_size(elf_file) return extracted
def logtrace_formated_print(recs, elfname, no_err): try: felf = elffile.ELFFile(open(elfname, 'rb')) except OSError as e: raise ESPLogTraceParserError("Failed to open ELF file (%s)!" % e) for lrec in recs: fmt_str = apptrace.get_str_from_elf(felf, lrec.fmt_addr) i = 0 prcnt_idx = 0 while i < len(lrec.args): prcnt_idx = fmt_str.find('%', prcnt_idx, -2) # TODO: check str ending with % if prcnt_idx == -1: break prcnt_idx += 1 # goto next char if fmt_str[prcnt_idx] == 's': # find string arg_str = apptrace.get_str_from_elf(felf, lrec.args[i]) if arg_str: lrec.args[i] = arg_str i += 1 # print("\nFmt = {%s}, args = %d/%s" % lrec) fmt_str = fmt_str.replace('%p', '%x') # print("=====> " + fmt_str % lrec.args) try: print(fmt_str % tuple(lrec.args), end='') # print(".", end='') pass except Exception as e: if not no_err: print("Print error (%s)" % e) print("\nFmt = {%s}, args = %d/%s" % (fmt_str, len(lrec.args), lrec.args)) felf.stream.close()
def __setstate__(self, data): self.__dict__.update(data) if self.binary_stream is None: self.binary_stream = open(self.binary, 'rb') else: self.binary_stream.stream = open(self.binary, 'rb') self.reader = elffile.ELFFile(self.binary_stream) if self._dynamic and 'DT_STRTAB' in self._dynamic: self.strtab = next(x for x in self.reader.iter_segments() if x.header.p_type == 'PT_DYNAMIC')._get_stringtable() if 'DT_SYMTAB' in self._dynamic and 'DT_SYMENT' in self._dynamic: fakesymtabheader = { 'sh_offset': AT.from_lva(self._dynamic['DT_SYMTAB'], self).to_rva(), 'sh_entsize': self._dynamic['DT_SYMENT'], 'sh_size': 0, # bogus size: no iteration allowed 'sh_flags': 0, 'sh_addralign': 0, } self.dynsym = elffile.SymbolTableSection(fakesymtabheader, 'symtab_cle', self.reader, self.strtab) self.dynsym.stream = self.memory if 'DT_GNU_HASH' in self._dynamic: self.hashtable = GNUHashTable( self.dynsym, self.memory, AT.from_lva(self._dynamic['DT_GNU_HASH'], self).to_rva(), self.arch) elif 'DT_HASH' in self._dynamic: self.hashtable = ELFHashTable( self.dynsym, self.memory, AT.from_lva(self._dynamic['DT_HASH'], self).to_rva(), self.arch)
def extract_sw_logs(elf_file, logs_fields_section, ro_sections): '''This function extracts contents from the logs fields section, and the read only sections, processes them and generates a tuple of (results) - log with fields and (rodata) - constant strings with their addresses. ''' # Open the elf file. with open(elf_file, 'rb') as f: elf = elffile.ELFFile(f) # Parse the ro sections to get {addr: string} pairs. ro_contents = [] for ro_section in ro_sections: section = elf.get_section_by_name(name=ro_section) if section: base_addr = int(section.header['sh_addr']) size = int(section.header['sh_size']) data = section.data() ro_contents.append((base_addr, size, data)) else: print("Error: {} section not found in {}".format( ro_section, elf_file)) sys.exit(1) addr_strings = get_addr_strings(ro_contents) # Dump the {addr: string} data. rodata = "" for addr in addr_strings.keys(): rodata += "addr: {}\n".format(hex(addr)[2:]) string = cleanup_newlines(addr_strings[addr]) rodata += "string: {}\n".format(string) # Parse the logs fields section to extract the logs. section = elf.get_section_by_name(name=logs_fields_section) if section: logs_base_addr = int(section.header['sh_addr']) logs_size = int(section.header['sh_size']) logs_data = section.data() else: print("Error: {} section not found in {}".format( logs_fields_section, elf_file)) sys.exit(1) # Dump the logs with fields. result = "" num_logs = logs_size // LOGS_FIELDS_SIZE for i in range(num_logs): start = i * LOGS_FIELDS_SIZE end = start + LOGS_FIELDS_SIZE severity, file_addr, line, nargs, format_addr = struct.unpack( 'IIIII', logs_data[start:end]) result += "addr: {}\n".format(hex(logs_base_addr + start)[2:]) result += "severity: {}\n".format(severity) result += "file: {}\n".format( prune_filename(get_str_at_addr(file_addr, addr_strings))) result += "line: {}\n".format(line) result += "nargs: {}\n".format(nargs) result += "format: {}\n".format( cleanup_format(get_str_at_addr(format_addr, addr_strings))) return rodata, result
def set_elf(self, stream): if self.elf: raise ValueError('ELF already set') self.elf = elf.ELFFile(stream) self.code = self.elf.get_section_by_name('.text').data() self._add_relocs(self.elf.get_section_by_name('.rela.text'))
def parse_fileobj(self, fileobj, *, use_segments=False, **kwargs): elf = elffile.ELFFile(fileobj) entry = elf['e_entry'] symbols = parse_elf_symbols(elf) if use_segments or elf.num_sections() == 0: mem = SegmentELFMemory(elf) else: mem = SectionELFMemory(elf) return ELFFile(self, mem, entry, symbols)
def __init__(self, elf_file_io: BinaryIO) -> None: """ Create ``elffile.ELFFile`` object and save it as class attribute. Args: elf_file_io: ELF file stream. """ self.elf_file_io = elf_file_io self.elf_file = elffile.ELFFile(stream=self.elf_file_io)
def set_input(self, input_): self._elf = elffile.ELFFile(input_) self.endianity = '<' if self._elf.little_endian else '>' self._segments = {} for s in self._elf.iter_segments(): if s.header['p_type'] != 'PT_LOAD': continue self.segments[s.header['p_vaddr']] = s.data()
def __init__(self, binary, **kwargs): super(ELF, self).__init__(binary, **kwargs) self.reader = elffile.ELFFile(open(self.binary, 'rb')) # Get an appropriate archinfo.Arch for this binary, unless the user specified one if self.arch is None: if self.reader.header.e_machine == 'EM_ARM' and \ self.reader.header.e_flags & 0x200: self.set_arch(archinfo.ArchARMEL('Iend_LE' if 'LSB' in self.reader.header.e_ident.EI_DATA else 'Iend_BE')) elif self.reader.header.e_machine == 'EM_ARM' and \ self.reader.header.e_flags & 0x400: self.set_arch(archinfo.ArchARMHF('Iend_LE' if 'LSB' in self.reader.header.e_ident.EI_DATA else 'Iend_BE')) else: self.set_arch(archinfo.arch_from_id(self.reader.header.e_machine, self.reader.header.e_ident.EI_DATA, self.reader.header.e_ident.EI_CLASS)) self.strtab = None self.dynsym = None self.hashtable = None self._dynamic = {} self.deps = [] self.rela_type = None self._inits_extracted = False self._preinit_arr = [] self._init_func = None self._init_arr = [] self._fini_func = None self._fini_arr = [] self._symbol_cache = {} self.symbols_by_addr = {} self.imports = {} self.resolved_imports = [] self.relocs = [] self.jmprel = {} self._entry = self.reader.header.e_entry self.pic = self.reader.header.e_type == 'ET_DYN' self.tls_used = False self.tls_module_id = None self.tls_block_offset = None self.tls_block_size = None self.tls_tdata_start = None self.tls_tdata_size = None self.__register_segments() self.__register_sections() # call the methods defined by MetaELF self._ppc64_abiv1_entry_fix() self._load_plt()
def extract_ota_data(binary_path, entries): with open(binary_path, 'rb') as f: elf = elffile.ELFFile(f) for entry in entries: if entry.is_resolved(): continue sect = elf.get_section_by_name(entry.section) if sect: entry.bytes = sect.data()
async def __get_symbol(self, name): with open(await self.binary, 'rb') as f: elf = elffile.ELFFile(f) name = name.encode('ascii') for section in elf.iter_sections(): if isinstance(section, elffile.SymbolTableSection): for symbol in section.iter_symbols(): sym_section = symbol['st_shndx'] if symbol.name == name and sym_section != 'SHN_UNDEF': return symbol['st_value']
def load_object_file(env, felf): with open(felf, "rb") as f: elf = elffile.ELFFile(f) env.check_arch(elf["e_machine"]) # Get symbol table symtab = list(elf.get_section_by_name(".symtab").iter_symbols()) # Load needed sections from ELF file sections_shndx = {} # maps elf shndx to Section object for idx, s in enumerate(elf.iter_sections()): if s.header.sh_type in ("SHT_PROGBITS", "SHT_NOBITS"): if s.data_size == 0: # Ignore empty sections pass elif s.name.startswith( (".literal", ".text", ".rodata", ".data.rel.ro", ".bss")): sec = Section.from_elfsec(s, felf) sections_shndx[idx] = sec if s.name.startswith(".literal"): env.literal_sections.append(sec) else: env.sections.append(sec) elif s.name.startswith(".data"): raise LinkError("{}: {} non-empty".format(felf, s.name)) else: # Ignore section pass elif s.header.sh_type in ("SHT_REL", "SHT_RELA"): shndx = s.header.sh_info if shndx in sections_shndx: sec = sections_shndx[shndx] sec.reloc_name = s.name sec.reloc = list(s.iter_relocations()) for r in sec.reloc: r.sym = symtab[r["r_info_sym"]] # Link symbols to their sections, and update known and unresolved symbols for sym in symtab: sym.filename = felf shndx = sym.entry["st_shndx"] if shndx in sections_shndx: # Symbol with associated section sym.section = sections_shndx[shndx] if sym["st_info"]["bind"] == "STB_GLOBAL": # Defined global symbol if sym.name in env.known_syms and not sym.name.startswith( "__x86.get_pc_thunk."): raise LinkError("duplicate symbol: {}".format( sym.name)) env.known_syms[sym.name] = sym elif sym.entry["st_shndx"] == "SHN_UNDEF" and sym["st_info"][ "bind"] == "STB_GLOBAL": # Undefined global symbol, needs resolving env.unresolved_syms.append(sym)
def load_object_file(env, felf): with open(felf, 'rb') as f: elf = elffile.ELFFile(f) env.check_arch(elf['e_machine']) # Get symbol table symtab = list(elf.get_section_by_name('.symtab').iter_symbols()) # Load needed sections from ELF file sections_shndx = {} # maps elf shndx to Section object for idx, s in enumerate(elf.iter_sections()): if s.header.sh_type in ('SHT_PROGBITS', 'SHT_NOBITS'): if s.data_size == 0: # Ignore empty sections pass elif s.name.startswith( ('.literal', '.text', '.rodata', '.data.rel.ro', '.bss')): sec = Section.from_elfsec(s, felf) sections_shndx[idx] = sec if s.name.startswith('.literal'): env.literal_sections.append(sec) else: env.sections.append(sec) elif s.name.startswith('.data'): raise LinkError('{}: {} non-empty'.format(felf, s.name)) else: # Ignore section pass elif s.header.sh_type in ('SHT_REL', 'SHT_RELA'): shndx = s.header.sh_info if shndx in sections_shndx: sec = sections_shndx[shndx] sec.reloc_name = s.name sec.reloc = list(s.iter_relocations()) for r in sec.reloc: r.sym = symtab[r['r_info_sym']] # Link symbols to their sections, and update known and unresolved symbols for sym in symtab: sym.filename = felf shndx = sym.entry['st_shndx'] if shndx in sections_shndx: # Symbol with associated section sym.section = sections_shndx[shndx] if sym['st_info']['bind'] == 'STB_GLOBAL': # Defined global symbol if sym.name in env.known_syms and not sym.name.startswith( '__x86.get_pc_thunk.'): raise LinkError('duplicate symbol: {}'.format( sym.name)) env.known_syms[sym.name] = sym elif sym.entry['st_shndx'] == 'SHN_UNDEF' and sym['st_info'][ 'bind'] == 'STB_GLOBAL': # Undefined global symbol, needs resolving env.unresolved_syms.append(sym)
def __init__(self, fd, session): self.session = session self.elffile = elffile.ELFFile(fd) self.types = {} if self.elffile.has_dwarf_info(): self._dwarfinfo = self.elffile.get_dwarf_info() else: raise RuntimeError("File does not have DWARF information - " "was it compiled with debugging information?") self.compile()
def extract_ota_code(params, binary_path): """Extracts text segment and data segment matadata. Data segment is compressed and the actual bytes returned are just placeholders that should be replaced with the app object file raw data. """ def seg_in_ota_flash(seg): return _seg_in_range(seg, params.ota_flash_addr, params.ota_flash_len) def seg_in_ota_sram(seg): return _seg_in_range(seg, params.ota_sram_addr, params.ota_sram_len) def seg_in_ota(seg): return seg_in_ota_flash(seg) or seg_in_ota_sram(seg) with open(binary_path, 'rb') as f: obj = elffile.ELFFile(f) segments = tuple( sorted( (s for s in obj.iter_segments() if seg_in_ota(s)), key=_seg_addr, ), ) segments = filter_segments(obj, segments) entrypoint = _find_entrypoint(obj) - params.ota_flash_addr #data = b'' data = bytearray() data_offset = params.ota_flash_addr loads = [] for seg in segments: if seg_in_ota_flash(seg): skip = seg.header.p_vaddr - data_offset data += (b'\x00' * skip) data_offset += skip seg_data = seg.data() data += seg_data data_offset += len(seg_data) else: loads.append( { 'offset': data_offset - params.ota_flash_addr, 'len': seg.header.p_memsz, 'dest': seg.header.p_vaddr, } ) f.seek(seg.header.p_offset, os.SEEK_SET) seg_data = bytes(seg.header.p_memsz) data += seg_data data_offset += seg.header.p_memsz return loads, entrypoint, data
def ELF_open(self, *dirs): p = self.profile.joinpath(*dirs) self.logger('opening {}'.format(p)) try: with open(p, 'rb') as f: yield ELF.ELFFile(f) except FileNotFoundError: yield except ELF.ELFError: yield finally: self.logger('closing {}'.format(p))
def parseElf(inFile): m = {} m["rom_rodata"] = 0 m["rom_code"] = 0 m["rom_misc"] = 0 m["ram_data"] = 0 m["ram_zdata"] = 0 heapStart = None ignoreSections = [ "", ".stack", ".comment", ".riscv.attributes", ".strtab", ".shstrtab" ] with open(inFile, "rb") as f: e = elffile.ELFFile(f) ramStart = e.get_segment(1)['p_paddr'] ramSize = e.get_segment(1)['p_memsz'] for s in e.iter_sections(): if s.name.startswith(".text"): m["rom_code"] += s.data_size elif s.name.startswith(".srodata"): m["rom_rodata"] += s.data_size elif s.name.startswith(".sdata"): m["ram_data"] += s.data_size elif s.name == ".rodata": m["rom_rodata"] += s.data_size elif (s.name == ".vectors" or s.name == ".init_array"): m["rom_misc"] += s.data_size elif s.name == ".data": m["ram_data"] += s.data_size elif s.name == ".bss" or s.name == ".sbss" or s.name == ".shbss": m["ram_zdata"] += s.data_size elif s.name.startswith(".gcc_except"): pass elif s.name.startswith(".sdata2"): pass elif s.name.startswith(".debug_"): pass elif s.name in ignoreSections: pass elif isinstance(s, SymbolTableSection): for sym in s.iter_symbols(): if sym.name == "_heap_start": heapStart = sym["st_value"] elif sym.name == "_min_stack": stackSize = sym["st_value"] else: print("warning: ignored: " + s.name + " / size: " + str(s.data_size)) return m, ramStart, ramSize, heapStart, stackSize
def __init__(self, elf_filename): self.load = [] # List of LoadSegments with open(elf_filename, 'rb') as h: elf = elffile.ELFFile(h) for segment in elf.iter_segments(): if segment['p_type'] == 'PT_LOAD': self.load.append( LoadSegment(data=segment.data(), address=segment['p_vaddr'])) self.entrypoint = elf['e_entry']
def get_soname(filename): """ Retrieve SONAME of shared library. Parameters ---------- filename : str Full path to shared library. Returns ------- soname : str SONAME of shared library. Notes ----- This function uses the pyelftools [ELF] package. References ---------- .. [ELF] http://pypi.python.org/pypi/pyelftools """ stream = open(filename, 'rb') f = elffile.ELFFile(stream) dynamic = f.get_section_by_name('.dynamic') dynstr = f.get_section_by_name('.dynstr') # Handle libraries built for different machine architectures: if f.header['e_machine'] == 'EM_X86_64': st = structs.Struct('Elf64_Dyn', macros.ULInt64('d_tag'), macros.ULInt64('d_val')) elif f.header['e_machine'] == 'EM_386': st = structs.Struct('Elf32_Dyn', macros.ULInt32('d_tag'), macros.ULInt32('d_val')) else: raise RuntimeError('unsupported machine architecture') entsize = dynamic['sh_entsize'] for k in xrange(dynamic['sh_size']/entsize): result = st.parse(dynamic.data()[k*entsize:(k+1)*entsize]) # The following value for the SONAME tag is specified in elf.h: if result.d_tag == 14: return dynstr.get_string(result.d_val) # No SONAME found: return ''
async def __get_symbol(self, name): if not await self.binary: raise Error( "ELF file not present for {}, cannot extract symbol ID of {}". format(self.name, name)) with open(await self.binary, 'rb') as f: elf = elffile.ELFFile(f) for section in elf.iter_sections(): if isinstance(section, elffile.SymbolTableSection): for symbol in section.iter_symbols(): sym_section = symbol['st_shndx'] if symbol.name == name and sym_section != 'SHN_UNDEF': return symbol['st_value']
def is_64_bit(input_file): """ Description: Do a quick check to see if it is an IDB/I64. Otherwise, attempt to determine if the file is 64bit based on the pe header. Note that the pe.close() prevents an mmap'd file from being left open indefinitely as the PE object doesn't seem to get garbage collected. Forcing garbage collection also corrects that issue. Input: input_file - The full path to the file in question Output: True if it is 64 bit. False if it is not or if pefile couldn't parse the header. """ if input_file.endswith('.i64'): return True elif input_file.endswith('.idb'): return False # Get first bytes of file to check the file magic with open(input_file, 'rb') as f: first_bytes = f.read(8) if first_bytes[0:2] == "\x4D\x5A": # PE file type try: pe = pefile.PE(input_file, fast_load=True) result = pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS pe.close() except: result = False elif first_bytes[1:4] == "\x45\x4C\x46": # elf file type try: with open(input_file, 'rb') as f: elf = elffile.ELFFile(f) result = elf.get_machine_arch() in ["AArch64", "x64"] except ELFError: result = False elif first_bytes[0:4] == "\xCE\xFA\xED\xFE": # 32 bit MACH-O executable result = False elif first_bytes[0:4] == "\xCF\xFA\xED\xFE": # 64 bit MACH-O executable result = True else: result = False return result
def get_lines(binary, base_address=0x0): elf_binary = elf.ELFFile(binary) dwarf = elf_binary.get_dwarf_info() lines = defaultdict(lambda: defaultdict(lambda: [])) for cu in dwarf.iter_CUs(): lp = dwarf.line_program_for_CU(cu) files = lp['file_entry'] directories = ["."] + [str(d, 'utf8') for d in lp['include_directory']] for lpe in lp.get_entries(): if lpe.state: lfile = files[lpe.state.file - 1] (lines[(directories[lfile['dir_index']], str(lfile['name'], 'utf8'))][lpe.state.line].append( (lpe.command, lpe.state.address + base_address))) return lines
def __process_debug_file(self, filename): with open(filename, 'rb') as fp: try: elf = elffile.ELFFile(fp) except ELFError: l.warning("pyelftools failed to load debug file %s", filename, exc_info=True) return for sec_readelf in elf.iter_sections(): if isinstance(sec_readelf, elffile.SymbolTableSection): self.__register_section_symbols(sec_readelf) elif sec_readelf.header.sh_type == 'SHT_NOTE': self.__register_notes(sec_readelf)
def __init__(self, bf_old, bf_new, obj_files, patchfile, mode): self.bf_old = bf_old self.bf_new = bf_new self.obj_files = [elffile.ELFFile(open(fn)) for fn in obj_files] self.patchfile = patchfile self.mode = mode self.common_func = [] old_func = self.bf_old.functions new_func = self.bf_new.functions common_func = list(set(old_func.keys()) & set(new_func.keys())) for name in common_func: fj = FuncJump(name, old_func[name], new_func[name]) self.common_func.append(fj)