Example #1
0
    def display_symbol_tables(self):
        """ Display the symbol tables contained in the file
        """
        for section in self.elffile.iter_sections():
            if not isinstance(section, SymbolTableSection):
                continue

            if section['sh_entsize'] == 0:
                self._emitline("\nSymbol table '%s' has a sh_entsize of zero!" % (
                    bytes2str(section.name)))
                continue

            self._emitline("\nSymbol table '%s' contains %s entries:" % (
                bytes2str(section.name), section.num_symbols()))

            if self.elffile.elfclass == 32:
                self._emitline('   Num:    Value  Size Type    Bind   Vis      Ndx Name')
            else: # 64
                self._emitline('   Num:    Value          Size Type    Bind   Vis      Ndx Name')

            for nsym, symbol in enumerate(section.iter_symbols()):
                # symbol names are truncated to 25 chars, similarly to readelf
                self._emitline('%6d: %s %5d %-7s %-6s %-7s %4s %.25s' % (
                    nsym,
                    self._format_hex(symbol['st_value'], fullhex=True, lead0x=False),
                    symbol['st_size'],
                    describe_symbol_type(symbol['st_info']['type']),
                    describe_symbol_bind(symbol['st_info']['bind']),
                    describe_symbol_visibility(symbol['st_other']['visibility']),
                    describe_symbol_shndx(symbol['st_shndx']),
                    bytes2str(symbol.name)))
Example #2
0
File: utils.py Project: zha0/qiling
    def elf_symbol_tables(self):
        symbol_tables_list = []

        def add_info(dic):
            symbol_tables_list.append(dic)

        self._init_versioninfo()

        symbol_tables = [
            s for s in self.elffile.iter_sections()
            if isinstance(s, SymbolTableSection)
        ]

        if not symbol_tables and self.elffile.num_sections() == 0:
            return None

        for section in symbol_tables:
            if not isinstance(section, SymbolTableSection):
                continue

            if section['sh_entsize'] == 0:
                continue

            for nsym, symbol in enumerate(section.iter_symbols()):
                version_info = ''
                if (section['sh_type'] == 'SHT_DYNSYM'
                        and self._versioninfo['type'] == 'GNU'):
                    version = self._symbol_version(nsym)
                    if (version['name'] != symbol.name and version['index']
                            not in ('VER_NDX_LOCAL', 'VER_NDX_GLOBAL')):
                        if version['filename']:
                            # external symbol
                            version_info = '@%(name)s (%(index)i)' % version
                        else:
                            # internal symbol
                            if version['hidden']:
                                version_info = '@%(name)s' % version
                            else:
                                version_info = '@@%(name)s' % version

                symbol_info = {}
                symbol_info['index'] = nsym
                symbol_info['Value'] = self._format_hex(symbol['st_value'],
                                                        fullhex=True,
                                                        lead0x=False)
                symbol_info['Size'] = symbol['st_size']
                symbol_info['Type'] = describe_symbol_type(
                    symbol['st_info']['type'])
                symbol_info['Bind'] = describe_symbol_bind(
                    symbol['st_info']['bind'])
                symbol_info['Vis'] = describe_symbol_visibility(
                    symbol['st_other']['visibility'])
                symbol_info['Ndx'] = describe_symbol_shndx(symbol['st_shndx'])
                symbol_info['Name'] = symbol.name
                symbol_info['version_info'] = version_info
                add_info(symbol_info)
        return symbol_tables_list
Example #3
0
    def display_symbol_tables(self):
        """ Display the symbol tables contained in the file
        """
        self._init_versioninfo()

        for section in self.elffile.iter_sections():
            if not isinstance(section, SymbolTableSection):
                continue

            if section['sh_entsize'] == 0:
                self._emitline("\nSymbol table '%s' has a sh_entsize of zero!" % (
                    bytes2str(section.name)))
                continue

            self._emitline("\nSymbol table '%s' contains %s entries:" % (
                bytes2str(section.name), section.num_symbols()))

            if self.elffile.elfclass == 32:
                self._emitline('   Num:    Value  Size Type    Bind   Vis      Ndx Name')
            else: # 64
                self._emitline('   Num:    Value          Size Type    Bind   Vis      Ndx Name')

            for nsym, symbol in enumerate(section.iter_symbols()):

                version_info = ''
                # readelf doesn't display version info for Solaris versioning
                if (section['sh_type'] == 'SHT_DYNSYM' and
                        self._versioninfo['type'] == 'GNU'):
                    version = self._symbol_version(nsym)
                    if (version['name'] != bytes2str(symbol.name) and
                        version['index'] not in ('VER_NDX_LOCAL',
                                                 'VER_NDX_GLOBAL')):
                        if version['filename']:
                            # external symbol
                            version_info = '@%(name)s (%(index)i)' % version
                        else:
                            # internal symbol
                            if version['hidden']:
                                version_info = '@%(name)s' % version
                            else:
                                version_info = '@@%(name)s' % version

                # symbol names are truncated to 25 chars, similarly to readelf
                self._emitline('%6d: %s %5d %-7s %-6s %-7s %4s %.25s%s' % (
                    nsym,
                    self._format_hex(
                        symbol['st_value'], fullhex=True, lead0x=False),
                    symbol['st_size'],
                    describe_symbol_type(symbol['st_info']['type']),
                    describe_symbol_bind(symbol['st_info']['bind']),
                    describe_symbol_visibility(symbol['st_other']['visibility']),
                    describe_symbol_shndx(symbol['st_shndx']),
                    bytes2str(symbol.name),
                    version_info))
Example #4
0
    def display_symbol_tables(self):
        """ Display the symbol tables contained in the file
        """
        for section in self.elffile.iter_sections():
            if not isinstance(section, SymbolTableSection):
                continue

            if section['sh_entsize'] == 0:
                self._emitline(
                    "\nSymbol table '%s' has a sh_entsize of zero!" %
                    (bytes2str(section.name)))
                continue

            self._emitline("\nSymbol table '%s' contains %s entries:" %
                           (bytes2str(section.name), section.num_symbols()))

            if self.elffile.elfclass == 32:
                self._emitline(
                    '   Num:    Value  Size Type    Bind   Vis      Ndx Name')
            else:  # 64
                self._emitline(
                    '   Num:    Value          Size Type    Bind   Vis      Ndx Name'
                )

            for nsym, symbol in enumerate(section.iter_symbols()):
                # symbol names are truncated to 25 chars, similarly to readelf
                self._emitline(
                    '%6d: %s %5d %-7s %-6s %-7s %4s %.25s' %
                    (nsym,
                     self._format_hex(symbol['st_value'],
                                      fullhex=True,
                                      lead0x=False), symbol['st_size'],
                     describe_symbol_type(symbol['st_info']['type']),
                     describe_symbol_bind(symbol['st_info']['bind']),
                     describe_symbol_visibility(
                         symbol['st_other']['visibility']),
                     describe_symbol_shndx(
                         symbol['st_shndx']), bytes2str(symbol.name)))
Example #5
0
    def get_symbols(self):
        """Return a set of symbols from the dwarf symbol tables"""
        symbols = {}

        # We want .symtab and .dynsym
        tables = [
            (idx, s)
            for idx, s in enumerate(self.elffile.iter_sections())
            if isinstance(s, SymbolTableSection)
        ]

        for idx, section in tables:
            # Symbol table has no entries if this is zero
            # section.num_symbols() shows count, section.name is name
            if section["sh_entsize"] == 0:
                continue

            # We need the index of the symbol to look up versions
            for sym_idx, symbol in enumerate(section.iter_symbols()):

                # Version info is from the versym / verneed / verdef sections.
                version_info = self._get_symbol_version(section, sym_idx, symbol)

                # We aren't considering st_value, which could be many things
                # https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcoblj/index.html#chapter6-35166
                symbols[symbol.name] = {
                    "version_info": version_info,
                    "type": describe_symbol_type(symbol["st_info"]["type"]),
                    "binding": describe_symbol_bind(symbol["st_info"]["bind"]),
                    "visibility": describe_symbol_visibility(
                        symbol["st_other"]["visibility"]
                    ),
                    "defined": describe_symbol_shndx(
                        self._get_symbol_shndx(symbol, sym_idx, idx)
                    ).strip(),
                }

        return symbols
Example #6
0
    def get_sections(self):
        sections = []
        for nsec, section in enumerate(self._elf.iter_sections()):
            result = {}
            result['nsec'] = nsec
            result['name'] = section.name
            result['sh_type'] = describe_sh_type(section['sh_type'])
            if self._elf.elfclass == 32:
                result['sh_addr'] = section['sh_addr']
                result['shoffset'] = section['sh_offset']
                result['sh_size'] = section['sh_size']
                result['sh_entsize'] = section['sh_entsize']
                result['sh_flags'] = describe_sh_flags(section['sh_flags'])
                result['sh_link'] = section['sh_link']
                result['sh_info'] = section['sh_info']
                result['sh_addralign'] = section['sh_addralign']
            else:  # 64
                result['sh_addr'] = section['sh_addr']
                result['sh_offset'] = section['sh_offset']
                result['sh_size'] = section['sh_size']
                result['sh_entsize'] = section['sh_entsize']
                result['sh_flags'] = describe_sh_flags(section['sh_flags'])
                result['sh_link'] = section['sh_link'], section['sh_info']
                result['sh_addralign'] = section['sh_addralign']

            # Dynamic Section
            if isinstance(section, DynamicSection):
                result['special_type'] = 'dynamic'
                result['dynamic'] = []
                has_dynamic_sections = True
                for tag in section.iter_tags():
                    dynamic = {}
                    if tag.entry.d_tag == 'DT_NEEDED':
                        parsed = 'Shared library: [%s]' % tag.needed
                    elif tag.entry.d_tag == 'DT_RPATH':
                        parsed = 'Library rpath: [%s]' % tag.rpath
                    elif tag.entry.d_tag == 'DT_RUNPATH':
                        parsed = 'Library runpath: [%s]' % tag.runpath
                    elif tag.entry.d_tag == 'DT_SONAME':
                        parsed = 'Library soname: [%s]' % tag.soname
                    elif tag.entry.d_tag.endswith(('SZ', 'ENT')):
                        parsed = '%i (bytes)' % tag['d_val']
                    elif tag.entry.d_tag.endswith(('NUM', 'COUNT')):
                        parsed = '%i' % tag['d_val']
                    elif tag.entry.d_tag == 'DT_PLTREL':
                        s = describe_dyn_tag(tag.entry.d_val)
                        if s.startswith('DT_'):
                            s = s[3:]
                        parsed = '%s' % s
                    else:
                        parsed = '%#x' % tag['d_val']
                        dynamic['tag'] = ENUM_D_TAG.get(
                            tag.entry.d_tag, tag.entry.d_tag)
                        dynamic['tag_type'] = tag.entry.d_tag[3:]
                        dynamic['tag_value'] = parsed
                    result['dynamic'].append(dynamic)

            #Relocation Section
            if isinstance(section, RelocationSection):
                result['special_type'] = 'relocation'
                result['relocation'] = []
                has_relocation_sections = True
                # The symbol table section pointed to in sh_link
                symtable = self._elf.get_section(section['sh_link'])

                for rel in section.iter_relocations():
                    relocation = {}
                    relocation['r_offset'] = rel['r_offset']
                    relocation['r_info'] = rel['r_info']
                    relocation['r_info_type'] = describe_reloc_type(
                        rel['r_info_type'], self._elf)

                    if rel['r_info_sym'] == 0:
                        continue

                    symbol = symtable.get_symbol(rel['r_info_sym'])
                    # Some symbols have zero 'st_name', so instead what's used is
                    # the name of the section they point at
                    if symbol['st_name'] == 0:
                        symsec = self._elf.get_section(symbol['st_shndx'])
                        relocation['symbol_name'] = symbol_name = symsec.name
                    else:
                        symbol_name = symbol.name
                        relocation['st_value'] = symbol['st_value']
                        relocation['symbol_name'] = symbol_name
                    if section.is_RELA():
                        relocation['r_addend'] = rel['r_addend']
                    result['relocation'].append(relocation)

            #Symbol Section
            if isinstance(section, SymbolTableSection):
                self._init_versioninfo()

                if section['sh_entsize'] == 0:
                    continue
                result['special_type'] = 'symbol'
                result['symbol'] = []
                for nsym, symbol in enumerate(section.iter_symbols()):
                    sym_dic = {}
                    version_info = ''
                    # readelf doesn't display version info for Solaris versioning
                    if (section['sh_type'] == 'SHT_DYNSYM'
                            and self._versioninfo['type'] == 'GNU'):
                        version = self._symbol_version(nsym)
                        if (version['name'] != symbol.name and version['index']
                                not in ('VER_NDX_LOCAL', 'VER_NDX_GLOBAL')):
                            if version['filename']:
                                # external symbol
                                version_info = '@%(name)s (%(index)i)' % version
                            else:
                                # internal symbol
                                if version['hidden']:
                                    version_info = '@%(name)s' % version
                                else:
                                    version_info = '@@%(name)s' % version

                        # symbol names are truncated to 25 chars, similarly to readelf
                        sym_dic['nsym'] = nsym
                        sym_dic['st_value'] = symbol['st_value']
                        sym_dic['st_size'] = symbol['st_size']
                        sym_dic['st_type'] = describe_symbol_type(
                            symbol['st_info']['type'])
                        sym_dic['bind'] = describe_symbol_bind(
                            symbol['st_info']['bind'])
                        sym_dic['vis'] = describe_symbol_visibility(
                            symbol['st_other']['visibility'])
                        sym_dic['ndx'] = describe_symbol_shndx(
                            symbol['st_shndx'])
                        sym_dic['name'] = symbol.name
                        sym_dic['version'] = version_info
                        result['symbol'].append(sym_dic)
            sections.append(result)
        return sections
Example #7
0
    def display_symbol_tables(self):
        """ Display the symbol tables contained in the file
		"""
        self._init_versioninfo()

        listSyms = []
        setClasses = set()

        for section in self.elffile.iter_sections():
            if not isinstance(section, SymbolTableSection):
                continue

            if section['sh_entsize'] == 0:
                continue

            for nsym, symbolobj in enumerate(section.iter_symbols()):

                version_info = ''
                # readelf doesn't display version info for Solaris versioning
                if (section['sh_type'] == 'SHT_DYNSYM'
                        and self._versioninfo['type'] == 'GNU'):
                    version = self._symbol_version(nsym)
                    if (version['name'] != symbolobj.name and version['index']
                            not in ('VER_NDX_LOCAL', 'VER_NDX_GLOBAL')):
                        if version['filename']:
                            # external symbol
                            version_info = '@%(name)s (%(index)i)' % version
                        else:
                            # internal symbol
                            if version['hidden']:
                                version_info = '@%(name)s' % version
                            else:
                                version_info = '@@%(name)s' % version

                demang = demangler.demangle(symbolobj.name)

                nnn = indexStartsWith(demang, "vtable for ")
                if nnn:
                    setClasses.add(nnn)
                    continue

                nnn = indexStartsWith(demang, "typeinfo name for ")
                if nnn:
                    setClasses.add(nnn)
                    continue

                nnn = indexStartsWith(demang, "typeinfo for ")
                if nnn:
                    setClasses.add(nnn)
                    continue

                nnn = indexStartsWith(demang, "non-virtual thunk to ")
                if nnn:
                    # No need to duplicate the symbol.
                    # demang = nnn
                    continue

                # Related to virtual inheritance.
                # http://stackoverflow.com/questions/6258559/what-is-the-vtt-for-a-class
                nnn = indexStartsWith(demang, "VTT for ")
                # TODO: Use it to build class hierarchy ???
                if nnn:
                    continue

                sym = ElfSym(
                    demang, symbolobj.name,
                    describe_symbol_type(symbolobj['st_info']['type']),
                    describe_symbol_bind(symbolobj['st_info']['bind']),
                    describe_symbol_visibility(
                        symbolobj['st_other']['visibility']),
                    describe_symbol_shndx(symbolobj['st_shndx']), version_info)

                listSyms.append(sym)

        return (listSyms, setClasses)