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
def load_symbols_elf(filename):
    """ Load the symbol tables contained in the file
    """
    f = open(filename, 'rb')

    elffile = ELFFile(f)

    symbols = []

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

        if section['sh_entsize'] == 0:
            logger.warn("Symbol table {} has a sh_entsize of zero.".format(section.name))

            continue

        logger.info("Symbol table {} contains {} entries.".format(section.name, section.num_symbols()))

        for _, symbol in enumerate(section.iter_symbols()):
            if describe_symbol_shndx(symbol['st_shndx']) != "UND" and \
                describe_symbol_type(symbol['st_info']['type']) == "FUNC":
                symbols.append((symbol['st_value'], symbol['st_size'], symbol.name))

    f.close()

    symbols_by_addr = {
        addr: (name, size, True) for addr, size, name in symbols
    }

    return symbols_by_addr
Example #3
0
 def display_symbol_tables(self):
     self._init_versioninfo()
     symbol_tables = [
         s for s in self.elffile.iter_sections()
         if isinstance(s, SymbolTableSection)
     ]
     imports = set()
     exports = set()
     for section in symbol_tables:
         if not isinstance(section, SymbolTableSection):
             continue
         if section['sh_entsize'] == 0:
             # print("\nSymbol table '%s' has a sh_entsize of zero!" % (section.name))
             continue
         for nsym, symbol in enumerate(section.iter_symbols()):
             sym_type = describe_symbol_type(symbol['st_info']['type'])
             if sym_type == "FUNC":
                 desc = describe_symbol_shndx(symbol['st_shndx'])
                 if desc == "UND":
                     imports.add(str(symbol.name))
                 try:
                     exports.add(str(symbol.name))
                 except ValueError:
                     pass
     self.data["imports"] = list(imports)
     self.data["exports"] = list(exports)
Example #4
0
 def _dump_elf(cls, buf):
     """
     Dump the symbol table of an ELF file.
     Needs pyelftools (https://github.com/eliben/pyelftools)
     """
     from elftools.elf.elffile import ELFFile
     from elftools.elf import descriptions
     from io import BytesIO
     f = ELFFile(BytesIO(buf))
     print("ELF file:")
     for sec in f.iter_sections():
         if sec['sh_type'] == 'SHT_SYMTAB':
             symbols = sorted(sec.iter_symbols(), key=lambda sym: sym.name)
             print("    symbols:")
             for sym in symbols:
                 if not sym.name:
                     continue
                 print("    - %r: size=%d, value=0x%x, type=%s, bind=%s"
                       % (sym.name.decode(),
                          sym['st_size'],
                          sym['st_value'],
                          descriptions.describe_symbol_type(sym['st_info']['type']),
                          descriptions.describe_symbol_bind(sym['st_info']['bind']),
                          ))
     print()
Example #5
0
def load_symbols_elf(filename):
    """ Load the symbol tables contained in the file
    """
    f = open(filename, 'rb')

    elffile = ELFFile(f)

    symbols = []

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

        if section['sh_entsize'] == 0:
            logger.warn("Symbol table {} has a sh_entsize of zero.".format(section.name))

            continue

        logger.info("Symbol table {} contains {} entries.".format(section.name, section.num_symbols()))

        for _, symbol in enumerate(section.iter_symbols()):
            if describe_symbol_shndx(symbol['st_shndx']) != "UND" and \
                describe_symbol_type(symbol['st_info']['type']) == "FUNC":
                symbols.append((symbol['st_value'], symbol['st_size'], symbol.name))

    f.close()

    symbols_by_addr = {
        addr: (name, size, True) for addr, size, name in symbols
    }

    return symbols_by_addr
Example #6
0
 def _dump_elf(cls, buf):
     """
     Dump the symbol table of an ELF file.
     Needs pyelftools (https://github.com/eliben/pyelftools)
     """
     from elftools.elf.elffile import ELFFile
     from elftools.elf import descriptions
     from io import BytesIO
     f = ELFFile(BytesIO(buf))
     print("ELF file:")
     for sec in f.iter_sections():
         if sec['sh_type'] == 'SHT_SYMTAB':
             symbols = sorted(sec.iter_symbols(), key=lambda sym: sym.name)
             print("    symbols:")
             for sym in symbols:
                 if not sym.name:
                     continue
                 print("    - %r: size=%d, value=0x%x, type=%s, bind=%s" % (
                     sym.name.decode(),
                     sym['st_size'],
                     sym['st_value'],
                     descriptions.describe_symbol_type(
                         sym['st_info']['type']),
                     descriptions.describe_symbol_bind(
                         sym['st_info']['bind']),
                 ))
     print()
Example #7
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 #8
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 #9
0
 def _get_symbol_tables(self):
     symbol_tables = []
     for section in self.elf.iter_sections():
         if not isinstance(section, SymbolTableSection):
             continue
         for nsym, symbol in enumerate(section.iter_symbols()):
             symbol_tables.append({
                 "value": self._print_addr(symbol["st_value"]),
                 "type": describe_symbol_type(symbol["st_info"]["type"]),
                 "bind": describe_symbol_bind(symbol["st_info"]["bind"]),
                 "ndx_name": symbol.name,
             })
     return symbol_tables
Example #10
0
 def _get_symbol_tables(self):
     symbol_tables = []
     for section in self.elf.iter_sections():
         if not isinstance(section, SymbolTableSection):
             continue
         for nsym, symbol in enumerate(section.iter_symbols()):
             symbol_tables.append({
                 "value": self._print_addr(symbol["st_value"]),
                 "type": describe_symbol_type(symbol["st_info"]["type"]),
                 "bind": describe_symbol_bind(symbol["st_info"]["bind"]),
                 "ndx_name": symbol.name,
             })
     return symbol_tables
Example #11
0
 def get_symbols(self,elf) -> list:
     '''
     get symbols and types 
     '''
     _list = []
     for section in elf.iter_sections():
         if not isinstance(section, SymbolTableSection):
             continue
         for symbol in section.iter_symbols():
             if len(symbol.name) > 0:
                 _list.append({  "Type":describe_symbol_type(symbol['st_info']['type']),
                                 "Symbol":symbol.name,
                                 "Description":""})
         return _list
Example #12
0
    def _get_symbol_tables(self) -> List[Dict[str, str]]:
        symbol_tables = []
        for section in self.elf.iter_sections():
            if not isinstance(section, SymbolTableSection):
                continue
            symbol_tables.extend(
                {
                    "value": self._print_addr(symbol["st_value"]),
                    "type": describe_symbol_type(symbol["st_info"]["type"]),
                    "bind": describe_symbol_bind(symbol["st_info"]["bind"]),
                    "ndx_name": symbol.name,
                }
                for symbol in section.iter_symbols()
            )

        return symbol_tables
Example #13
0
    def symbols(self):
        if not self.__check_session():
            return

        rows = []
        for section in self.elf.iter_sections():
            if not isinstance(section, SymbolTableSection): continue

            for cnt, symbol in enumerate(section.iter_symbols()):
                rows.append([
                    cnt,
                    hex(symbol['st_value']),
                    hex(symbol['st_size']),
                    describe_symbol_type(symbol['st_info']['type']),
                    symbol.name
                ])
        
        print_info("ELF Symbols:")
        print(table(header=['Num', 'Value', 'Size', 'Type', 'Name'], rows=rows))
Example #14
0
    def symbols(self):
        if not self.__check_session():
            return

        rows = []
        for section in self.elf.iter_sections():
            if not isinstance(section, SymbolTableSection):
                continue

            for cnt, symbol in enumerate(section.iter_symbols()):
                rows.append([
                    cnt,
                    hex(symbol['st_value']),
                    hex(symbol['st_size']),
                    describe_symbol_type(symbol['st_info']['type']),
                    symbol.name
                ])

        self.log('info', "ELF Symbols:")
        self.log('table', dict(header=['Num', 'Value', 'Size', 'Type', 'Name'], rows=rows))
Example #15
0
    def parse_symbol_table(self):
        """ build symbol table data structure

        :return: list of symbols
        """
        if self.symbol_table is None:
            self.symbol_table = SymbolTable()

            symbol_tables = [
                section for section in self._elf.iter_sections()
                if isinstance(section, SymbolTableSection)
            ]
            for section in symbol_tables:
                for symbol in section.iter_symbols():
                    if ((int(symbol["st_size"]) > 0)
                            and ("OBJECT" == describe_symbol_type(
                                symbol["st_info"]["type"]))):
                        symbol_entry = Symbol(symbol.name, symbol["st_value"],
                                              symbol["st_size"])
                        self.symbol_table.add_symbol(symbol_entry)

        return self.symbol_table
Example #16
0
    def symbols(self):
        if not self.__check_session():
            return

        rows = []
        for section in self.elf.iter_sections():
            if not isinstance(section, SymbolTableSection):
                continue

            for cnt, symbol in enumerate(section.iter_symbols()):
                rows.append(
                    [
                        cnt,
                        hex(symbol["st_value"]),
                        hex(symbol["st_size"]),
                        describe_symbol_type(symbol["st_info"]["type"]),
                        symbol.name,
                    ]
                )

        print_info("ELF Symbols:")
        print(table(header=["Num", "Value", "Size", "Type", "Name"], rows=rows))
Example #17
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 #18
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 #19
0
    def scan(self, data, file, options, expire_at):
        with io.BytesIO(data) as elf_io:
            try:
                elf = elffile.ELFFile(elf_io)

                self.event.setdefault('header', {})
                for (key, value) in elf.header.items():
                    if key == 'e_flags':
                        self.event['header']['flags'] = value
                    elif key == 'e_shnum':
                        self.event['header']['section_headers'] = value
                    elif key == 'e_phnum':
                        self.event['header']['program_headers'] = value
                    elif key == 'e_version':
                        self.event['header'][
                            'file_version'] = descriptions.describe_e_version_numeric(
                                value)
                    elif key == 'e_machine':
                        self.event['header'][
                            'machine'] = descriptions.describe_e_machine(value)
                    elif key == 'e_type':
                        self.event['header'][
                            'file_type'] = descriptions.describe_e_type(value)
                    elif key == 'e_ident':
                        for x, y in value.items():
                            if x == 'EI_DATA':
                                self.event['header'][
                                    'data'] = descriptions.describe_ei_data(y)
                            elif x == 'EI_OSABI':
                                self.event['header'][
                                    'os_abi'] = descriptions.describe_ei_osabi(
                                        y)
                            elif x == 'EI_VERSION':
                                self.event['header'][
                                    'header_version'] = descriptions.describe_ei_version(
                                        y)
                            elif x == 'EI_CLASS':
                                self.event['header'][
                                    'class'] = descriptions.describe_ei_class(
                                        y)
                            elif x == 'EI_ABIVERSION':
                                self.event['header']['abi_version'] = y

                try:
                    self.event.setdefault('shared_libraries', [])
                    self.event.setdefault('imports', [])
                    self.event.setdefault('exports', [])
                    for section in elf.iter_sections():
                        if not section.is_null():
                            if isinstance(section, dynamic.DynamicSection):
                                for tag in section.iter_tags():
                                    if tag.entry.d_tag == 'DT_NEEDED':
                                        if tag.needed not in self.event[
                                                'shared_libraries']:
                                            self.event[
                                                'shared_libraries'].append(
                                                    tag.needed)

                            # Attempt to organize symbols into imports and exports
                            # This is the most comprehensive explanation I've seen for organizing these symbols: http://www.m4b.io/elf/export/binary/analysis/2015/05/25/what-is-an-elf-export.html
                            if isinstance(section,
                                          sections.SymbolTableSection):
                                for symbol in section.iter_symbols():
                                    if descriptions.describe_symbol_type(
                                            symbol['st_info']['type']) in [
                                                'FUNC', 'OBJECT'
                                            ]:
                                        if descriptions.describe_symbol_bind(
                                                symbol['st_info']['bind']) in [
                                                    'GLOBAL', 'WEAK'
                                                ]:
                                            if descriptions.describe_symbol_shndx(
                                                    symbol['st_shndx']
                                            ) == 'UND':
                                                if symbol.name not in self.event[
                                                        'imports']:
                                                    self.event[
                                                        'imports'].append(
                                                            symbol.name)
                                            else:
                                                if symbol.name not in self.event[
                                                        'exports']:
                                                    self.event[
                                                        'exports'].append(
                                                            symbol.name)

                except OverflowError:
                    self.flags.append('overflow_error')

                self.event.setdefault('segments', [])
                segment_cache = {}
                for segment in elf.iter_segments():
                    for section in elf.iter_sections():
                        if not section.is_null(
                        ) and segment.section_in_segment(section):
                            key = segment.header['p_type']
                            if key not in self.event['segments']:
                                self.event['segments'].append(key)
                                segment_cache.setdefault(key, [])
                            segment_cache[key].append(section.name)

                self.event.setdefault('segment_sections', [])
                for (key, value) in segment_cache.items():
                    section_dict = {'segment': key, 'sections': value}
                    if section_dict not in self.event['segment_sections']:
                        self.event['segment_sections'].append(section_dict)

            except exceptions.ELFParseError:
                self.flags.append('elf_parse_error')
Example #20
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 #21
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)