def _get_dynamic_tags(self): dynamic_tags = [] for section in self.elf.iter_sections(): if not isinstance(section, DynamicSection): continue for tag in section.iter_tags(): dynamic_tags.append({ "tag": self._print_addr( ENUM_D_TAG.get(tag.entry.d_tag, tag.entry.d_tag) ), "type": tag.entry.d_tag[3:], "value": self._parse_tag(tag), }) return dynamic_tags
def _get_dynamic_tags(self) -> List[Dict[str, str]]: dynamic_tags = [] for section in self.elf.iter_sections(): if not isinstance(section, DynamicSection): continue dynamic_tags.extend( { "tag": self._print_addr(ENUM_D_TAG.get(tag.entry.d_tag, tag.entry.d_tag)), "type": str(tag.entry.d_tag)[3:], "value": self._parse_tag(tag), } for tag in section.iter_tags() ) return dynamic_tags
def display_dynamic_tags(self): """ Display the dynamic tags contained in the file """ has_dynamic_sections = False for section in self.elffile.iter_sections(): if not isinstance(section, DynamicSection): continue has_dynamic_sections = True self._emitline("\nDynamic section at offset %s contains %s entries:" % ( self._format_hex(section['sh_offset']), section.num_tags())) self._emitline(" Tag Type Name/Value") padding = 20 + (8 if self.elffile.elfclass == 32 else 0) for tag in section.iter_tags(): if tag.entry.d_tag == 'DT_NEEDED': parsed = 'Shared library: [%s]' % bytes2str(tag.needed) elif tag.entry.d_tag == 'DT_RPATH': parsed = 'Library rpath: [%s]' % bytes2str(tag.rpath) elif tag.entry.d_tag == 'DT_RUNPATH': parsed = 'Library runpath: [%s]' % bytes2str(tag.runpath) elif tag.entry.d_tag == 'DT_SONAME': parsed = 'Library soname: [%s]' % bytes2str(tag.soname) elif (tag.entry.d_tag.endswith('SZ') or tag.entry.d_tag.endswith('ENT')): parsed = '%i (bytes)' % tag['d_val'] elif (tag.entry.d_tag.endswith('NUM') or tag.entry.d_tag.endswith('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'] self._emitline(" %s %-*s %s" % ( self._format_hex(ENUM_D_TAG.get(tag.entry.d_tag, tag.entry.d_tag), fullhex=True, lead0x=True), padding, '(%s)' % (tag.entry.d_tag[3:],), parsed)) if not has_dynamic_sections: # readelf only prints this if there is at least one segment if self.elffile.num_segments(): self._emitline("\nThere is no dynamic section in this file.")
def _get_dynamic_tags(self): dynamic_tags = [] for section in self.elf.iter_sections(): if not isinstance(section, DynamicSection): continue for tag in section.iter_tags(): dynamic_tags.append({ "tag": self._print_addr( ENUM_D_TAG.get(tag.entry.d_tag, tag.entry.d_tag)), "type": tag.entry.d_tag[3:], "value": self._parse_tag(tag), }) return dynamic_tags
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