Fix formatting of some dynamic tag fields to match readelf
[pyelftools.git] / examples / elf_low_high_api.py
1 #-------------------------------------------------------------------------------
2 # elftools example: elf_low_high_api.py
3 #
4 # A simple example that shows some usage of the low-level API pyelftools
5 # provides versus the high-level API while inspecting an ELF file's symbol
6 # table.
7 #
8 # Eli Bendersky (eliben@gmail.com)
9 # This code is in the public domain
10 #-------------------------------------------------------------------------------
11 from __future__ import print_function
12 import sys
13
14 # If elftools is not installed, maybe we're running from the root or examples
15 # dir of the source distribution
16 try:
17 import elftools
18 except ImportError:
19 sys.path.extend(['.', '..'])
20
21 from elftools.common.py3compat import bytes2str
22 from elftools.elf.elffile import ELFFile
23 from elftools.elf.sections import SymbolTableSection
24
25
26 def process_file(filename):
27 print('Processing file:', filename)
28 with open(filename, 'rb') as f:
29 section_info_lowlevel(f)
30 f.seek(0)
31 section_info_highlevel(f)
32
33
34 def section_info_lowlevel(stream):
35 print('Low level API...')
36 # We'll still be using the ELFFile context object. It's just too
37 # convenient to give up, even in the low-level API demonstation :-)
38 elffile = ELFFile(stream)
39
40 # The e_shnum ELF header field says how many sections there are in a file
41 print(' %s sections' % elffile['e_shnum'])
42
43 # Try to find the symbol table
44 for i in range(elffile['e_shnum']):
45 section_offset = elffile['e_shoff'] + i * elffile['e_shentsize']
46 # Parse the section header using structs.Elf_Shdr
47 stream.seek(section_offset)
48 section_header = elffile.structs.Elf_Shdr.parse_stream(stream)
49 if section_header['sh_type'] == 'SHT_SYMTAB':
50 # Some details about the section. Note that the section name is a
51 # pointer to the object's string table, so it's only a number
52 # here. To get to the actual name one would need to parse the string
53 # table section and extract the name from there (or use the
54 # high-level API!)
55 print(' Section name: %s, type: %s' % (
56 section_header['sh_name'], section_header['sh_type']))
57 break
58 else:
59 print(' No symbol table found. Perhaps this ELF has been stripped?')
60
61
62 def section_info_highlevel(stream):
63 print('High level API...')
64 elffile = ELFFile(stream)
65
66 # Just use the public methods of ELFFile to get what we need
67 # Note that section names, like everything read from the file, are bytes
68 # objects.
69 print(' %s sections' % elffile.num_sections())
70 section = elffile.get_section_by_name(b'.symtab')
71
72 if not section:
73 print(' No symbol table found. Perhaps this ELF has been stripped?')
74 return
75
76 # A section type is in its header, but the name was decoded and placed in
77 # a public attribute.
78 # bytes2str is used to print the name of the section for consistency of
79 # output between Python 2 and 3. The section name is a bytes object.
80 print(' Section name: %s, type: %s' %(
81 bytes2str(section.name), section['sh_type']))
82
83 # But there's more... If this section is a symbol table section (which is
84 # the case in the sample ELF file that comes with the examples), we can
85 # get some more information about it.
86 if isinstance(section, SymbolTableSection):
87 num_symbols = section.num_symbols()
88 print(" It's a symbol section with %s symbols" % num_symbols)
89 print(" The name of the last symbol in the section is: %s" % (
90 bytes2str(section.get_symbol(num_symbols - 1).name)))
91
92
93 if __name__ == '__main__':
94 for filename in sys.argv[1:]:
95 process_file(filename)
96
97