예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
    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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
 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)
예제 #7
0
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
예제 #8
0
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()
예제 #9
0
파일: elf.py 프로젝트: mephi42/cle
    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)
예제 #10
0
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
예제 #11
0
    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'))
예제 #12
0
 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)
예제 #13
0
    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)
예제 #14
0
    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()
예제 #15
0
파일: elf.py 프로젝트: zhuyue1314/cle
    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()
예제 #16
0
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()
예제 #17
0
 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']
예제 #18
0
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)
예제 #19
0
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)
예제 #20
0
    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()
예제 #21
0
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
예제 #22
0
 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))
예제 #23
0
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
예제 #24
0
    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']
예제 #25
0
    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 ''
예제 #26
0
    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']
예제 #27
0
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
예제 #28
0
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
예제 #29
0
    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)
예제 #30
0
파일: binpatch.py 프로젝트: paboldin/nsb
    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)