From 53e86db9ed313451aa1165d89c1cdece16d33723 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sun, 18 Sep 2011 06:04:30 +0300 Subject: [PATCH] implemented string dumping, with tests --- scripts/readelf.py | 50 +++++++++++++++++++++++++++++++++++++++++++++- tests/run_tests.py | 16 ++++++++++++--- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/scripts/readelf.py b/scripts/readelf.py index 9b81fb7..44e15db 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -7,8 +7,10 @@ # Eli Bendersky (eliben@gmail.com) # This code is in the public domain #------------------------------------------------------------------------------- -import sys +import os, sys from optparse import OptionParser +import string + # If elftools is not installed, maybe we're running from the root or scripts # dir of the source distribution @@ -308,6 +310,46 @@ class ReadElf(object): self._emitline() + def display_string_dump(self, section_spec): + """ Display a strings dump of a section. section_spec is either a + section number or a name. + """ + secnum = self._section_num_from_spec(section_spec) + if secnum is None: + self._emitline("Section '%s' does not exist in the file!" % ( + section_spec)) + return + + printables = set(string.printable) + + section = self.elffile.get_section(secnum) + self._emitline("\nString dump of section '%s':" % section.name) + + found = False + data = section.data() + dataptr = 0 + + while dataptr < len(data): + while dataptr < len(data) and data[dataptr] not in printables: + dataptr += 1 + + if dataptr >= len(data): + break + + endptr = dataptr + while endptr < len(data) and data[endptr] != '\x00': + endptr += 1 + + found = True + self._emitline(' [%6x] %s' % ( + dataptr, data[dataptr:endptr])) + + dataptr = endptr + + if not found: + self._emitline(' No strings found in this section.') + else: + self._emitline() def _format_hex(self, addr, fieldsize=None, fullhex=False, lead0x=True): """ Format an address into a hexadecimal string. @@ -391,6 +433,10 @@ def main(): optparser.add_option('-x', '--hex-dump', action='store', dest='show_hex_dump', metavar='', help='Dump the contents of section as bytes') + optparser.add_option('-p', '--string-dump', + action='store', dest='show_string_dump', metavar='', + help='Dump the contents of section as strings') + options, args = optparser.parse_args() if options.help or len(args) == 0: @@ -419,6 +465,8 @@ def main(): readelf.display_symbol_tables() if options.show_hex_dump: readelf.display_hex_dump(options.show_hex_dump) + if options.show_string_dump: + readelf.display_string_dump(options.show_string_dump) except ELFError as ex: sys.stderr.write('ELF error: %s\n' % ex) sys.exit(1) diff --git a/tests/run_tests.py b/tests/run_tests.py index 85a9a41..ccc459e 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -44,10 +44,12 @@ def run_exe(exe_path, args): def run_test_on_file(filename): - """ Runs a test on the given input filename + """ Runs a test on the given input filename. Return True if all test + runs succeeded. """ + success = True testlog.info("Running test on file '%s'" % filename) - for option in ['-e', '-s', '-x.text']: + for option in ['-e', '-s', '-x.text', '-p.shstrtab']: testlog.info("..option='%s'" % option) # stdouts will be a 2-element list: output of readelf and output # of scripts/readelf.py @@ -66,9 +68,11 @@ def run_test_on_file(filename): if success: testlog.info('.......................SUCCESS') else: + success = False testlog.info('.......................FAIL') testlog.info('@@ ' + errmsg) dump_output_to_temp_files(*stdouts) + return success def compare_output(s1, s2): @@ -141,8 +145,14 @@ def main(): if not is_in_rootdir(): die('Please run me from the root dir of pyelftools!') + success = True for filename in discover_testfiles('tests/testfiles'): - run_test_on_file(filename) + success = success and run_test_on_file(filename) + + if success: + testlog.info('\nConclusion: SUCCESS') + else: + testlog.info('\nConclusion: FAIL') if __name__ == '__main__': -- 2.30.2