From 377bd86a2f1dd6318bbb76a1da6fe14e61e4bd05 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 16 Sep 2011 11:10:44 +0300 Subject: [PATCH] section header output kinda working --- elftools/elf/constants.py | 1 + elftools/elf/descriptions.py | 53 +++++++++++++++++++++++++++++- elftools/elf/enums.py | 5 ++- scripts/readelf.py | 63 ++++++++++++++++++++++++++++++++---- 4 files changed, 114 insertions(+), 8 deletions(-) diff --git a/elftools/elf/constants.py b/elftools/elf/constants.py index 1d49d2b..df75e16 100644 --- a/elftools/elf/constants.py +++ b/elftools/elf/constants.py @@ -32,6 +32,7 @@ class SH_FLAGS(object): SHF_GROUP=0x200 SHF_TLS=0x400 SHF_MASKOS=0x0ff00000 + SHF_EXCLUDE=0x80000000 SHF_MASKPROC=0xf0000000 diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index 258fc67..688ee61 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -7,7 +7,7 @@ # This code is in the public domain #------------------------------------------------------------------------------- from .enums import ENUM_E_VERSION -from .constants import P_FLAGS +from .constants import P_FLAGS, SH_FLAGS def describe_ei_class(x): @@ -43,6 +43,19 @@ def describe_p_flags(x): s += _DESCR_P_FLAGS[flag] if (x & flag) else ' ' return s +def describe_sh_type(x): + return _DESCR_SH_TYPE.get(x, _unknown()) + +def describe_sh_flags(x): + s = '' + for flag in ( + SH_FLAGS.SHF_WRITE, SH_FLAGS.SHF_ALLOC, SH_FLAGS.SHF_EXECINSTR, + SH_FLAGS.SHF_MERGE, SH_FLAGS.SHF_STRINGS, SH_FLAGS.SHF_INFO_LINK, + SH_FLAGS.SHF_LINK_ORDER, SH_FLAGS.SHF_OS_NONCONFORMING, + SH_FLAGS.SHF_GROUP, SH_FLAGS.SHF_TLS, SH_FLAGS.SHF_EXCLUDE): + s += _DESCR_SH_FLAGS[flag] if (x & flag) else '' + return s + #------------------------------------------------------------------------------- def _unknown(): @@ -126,4 +139,42 @@ _DESCR_P_FLAGS = { P_FLAGS.PF_W: 'W', } +_DESCR_SH_TYPE = dict( + SHT_NULL='NULL', + SHT_PROGBITS='PROGBITS', + SHT_SYMTAB='SYMTAB', + SHT_STRTAB='STRTAB', + SHT_RELA='RELA', + SHT_HASH='HASH', + SHT_DYNAMIC='DYNAMIC', + SHT_NOTE='NOTE', + SHT_NOBITS='NOBITS', + SHT_REL='REL', + SHT_SHLIB='SHLIB', + SHT_DYNSYM='DYNSYM', + SHT_INIT_ARRAY='INIT_ARRAY', + SHT_FINI_ARRAY='FINI_ARRAY', + SHT_PREINIT_ARRAY='PREINIT_ARRAY', + SHT_GNU_HASH='GNU_HASH', + SHT_GROUP='GROUP', + SHT_SYMTAB_SHNDX='SYMTAB SECTION INDICIES', + SHT_GNU_verdef='VERDEF', + SHT_GNU_verneed='VERNEED', + SHT_GNU_versym='VERSYM', + SHT_GNU_LIBLIST='GNU_LIBLIST', +) + +_DESCR_SH_FLAGS = { + SH_FLAGS.SHF_WRITE: 'W', + SH_FLAGS.SHF_ALLOC: 'A', + SH_FLAGS.SHF_EXECINSTR: 'X', + SH_FLAGS.SHF_MERGE: 'M', + SH_FLAGS.SHF_STRINGS: 'S', + SH_FLAGS.SHF_INFO_LINK: 'I', + SH_FLAGS.SHF_LINK_ORDER: 'L', + SH_FLAGS.SHF_OS_NONCONFORMING: 'O', + SH_FLAGS.SHF_GROUP: 'G', + SH_FLAGS.SHF_TLS: 'T', + SH_FLAGS.SHF_EXCLUDE: 'E', +} diff --git a/elftools/elf/enums.py b/elftools/elf/enums.py index 8715bf1..dadf5d4 100644 --- a/elftools/elf/enums.py +++ b/elftools/elf/enums.py @@ -100,7 +100,10 @@ ENUM_SH_TYPE = dict( SHT_SYMTAB_SHNDX=18, SHT_NUM=19, SHT_LOOS=0x60000000, - SHT_HIOS=0x6fffffff, + SHT_GNU_HASH=0x6ffffff6, + SHT_GNU_verdef=0x6ffffffd, + SHT_GNU_verneed=0x6ffffffe, + SHT_GNU_versym=0x6fffffff, SHT_LOPROC=0x70000000, SHT_HIPROC=0x7fffffff, SHT_LOUSER=0x80000000, diff --git a/scripts/readelf.py b/scripts/readelf.py index e6addb7..ede8738 100644 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -24,7 +24,7 @@ from elftools.elf.descriptions import ( describe_ei_class, describe_ei_data, describe_ei_version, describe_ei_osabi, describe_e_type, describe_e_machine, describe_e_version_numeric, describe_p_type, describe_p_flags, - + describe_sh_type, describe_sh_flags, ) @@ -95,11 +95,13 @@ class ReadElf(object): self._emitline() elfheader = self.elffile.header self._emitline('Elf file type is %s' % - describe_e_type(elfheader['e_type'])) + describe_e_type(elfheader['e_type'])) self._emitline('Entry point is %s' % - self._format_hex(elfheader['e_entry'])) + self._format_hex(elfheader['e_entry'])) + # readelf weirness - why isn't e_phoff printed as hex? (for section + # headers, it is...) self._emitline('There are %s program headers, starting at offset %s' % ( - elfheader['e_phnum'], elfheader['e_phoff'])) + elfheader['e_phnum'], elfheader['e_phoff'])) self._emitline('\nProgram headers:') @@ -165,9 +167,57 @@ class ReadElf(object): self._emitline('') + def display_section_headers(self): + """ Display the ELF section headers + """ + elfheader = self.elffile.header + self._emitline('There are %s section headers, starting at offset %s' % ( + elfheader['e_shnum'], self._format_hex(elfheader['e_shoff']))) + self._emitline('\nSection header%s:' % ( + 's' if elfheader['e_shnum'] > 1 else '')) + + # Different formatting constraints of 32-bit and 64-bit addresses + # + if self.elffile.elfclass == 32: + self._emitline(' [Nr] Name Type Addr Off Size ES Flg Lk Inf Al') + else: + self._emitline(' [Nr] Name Type Address Offset') + self._emitline(' Size EntSize Flags Link Info Align') + + # Now the entries + # + for nsec, section in enumerate(self.elffile.iter_sections()): + self._emit(' [%2u] %-17.17s %-15.15s ' % ( + nsec, section.name, describe_sh_type(section['sh_type']))) + + if self.elffile.elfclass == 32: + self._emitline('%s %s %s %s %3s %2s %3s %2s' % ( + self._format_hex(section['sh_addr'], fieldsize=8, lead0x=False), + self._format_hex(section['sh_offset'], fieldsize=6, lead0x=False), + self._format_hex(section['sh_size'], fieldsize=6, lead0x=False), + self._format_hex(section['sh_entsize'], fieldsize=2, lead0x=False), + describe_sh_flags(section['sh_flags']), + section['sh_link'], section['sh_info'], + section['sh_addralign'])) + else: # 64 + self._emitline(' %s %s' % ( + self._format_hex(section['sh_addr'], fullhex=True, lead0x=False), + self._format_hex(section['sh_offset'], + fieldsize=16 if section['sh_offset'] > 0xffffffff else 8, + lead0x=False))) + self._emitline(' %s %s %3s %2s %3s %s' % ( + self._format_hex(section['sh_size'], fullhex=True, lead0x=False), + self._format_hex(section['sh_entsize'], fullhex=True, lead0x=False), + describe_sh_flags(section['sh_flags']), + section['sh_link'], section['sh_info'], + section['sh_addralign'])) + + self._emitline('Key to Flags:') + self._emitline(' W (write), A (alloc), X (execute), M (merge), S (strings)') + self._emitline(' I (info), L (link order), G (group), x (unknown)') + self._emitline(' O (extra OS processing required) o (OS specific), p (processor specific)') - def _format_hex(self, addr, fieldsize=None, fullhex=False, lead0x=True): """ Format an address into a hexadecimal string. @@ -213,7 +263,8 @@ def main(): readelf = ReadElf(file, sys.stdout) readelf.display_file_header() print '----' - readelf.display_program_headers() + #readelf.display_program_headers() + readelf.display_section_headers() except ELFError as ex: sys.stderr.write('ELF read error: %s\n' % ex) sys.exit(1) -- 2.30.2