1 #-------------------------------------------------------------------------------
2 # elftools example: elf_low_high_api.py
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
8 # Eli Bendersky (eliben@gmail.com)
9 # This code is in the public domain
10 #-------------------------------------------------------------------------------
11 from __future__
import print_function
14 # If pyelftools is not installed, the example can also run from the root or
15 # examples/ dir of the source distribution.
16 sys
.path
[0:0] = ['.', '..']
18 from elftools
.common
.py3compat
import bytes2str
19 from elftools
.elf
.elffile
import ELFFile
20 from elftools
.elf
.sections
import SymbolTableSection
23 def process_file(filename
):
24 print('Processing file:', filename
)
25 with
open(filename
, 'rb') as f
:
26 section_info_lowlevel(f
)
28 section_info_highlevel(f
)
31 def section_info_lowlevel(stream
):
32 print('Low level API...')
33 # We'll still be using the ELFFile context object. It's just too
34 # convenient to give up, even in the low-level API demonstation :-)
35 elffile
= ELFFile(stream
)
37 # The e_shnum ELF header field says how many sections there are in a file
38 print(' %s sections' % elffile
['e_shnum'])
40 # Try to find the symbol table
41 for i
in range(elffile
['e_shnum']):
42 section_offset
= elffile
['e_shoff'] + i
* elffile
['e_shentsize']
43 # Parse the section header using structs.Elf_Shdr
44 stream
.seek(section_offset
)
45 section_header
= elffile
.structs
.Elf_Shdr
.parse_stream(stream
)
46 if section_header
['sh_type'] == 'SHT_SYMTAB':
47 # Some details about the section. Note that the section name is a
48 # pointer to the object's string table, so it's only a number
49 # here. To get to the actual name one would need to parse the string
50 # table section and extract the name from there (or use the
52 print(' Section name: %s, type: %s' % (
53 section_header
['sh_name'], section_header
['sh_type']))
56 print(' No symbol table found. Perhaps this ELF has been stripped?')
59 def section_info_highlevel(stream
):
60 print('High level API...')
61 elffile
= ELFFile(stream
)
63 # Just use the public methods of ELFFile to get what we need
64 # Note that section names, like everything read from the file, are bytes
66 print(' %s sections' % elffile
.num_sections())
67 section
= elffile
.get_section_by_name(b
'.symtab')
70 print(' No symbol table found. Perhaps this ELF has been stripped?')
73 # A section type is in its header, but the name was decoded and placed in
75 # bytes2str is used to print the name of the section for consistency of
76 # output between Python 2 and 3. The section name is a bytes object.
77 print(' Section name: %s, type: %s' %(
78 bytes2str(section
.name
), section
['sh_type']))
80 # But there's more... If this section is a symbol table section (which is
81 # the case in the sample ELF file that comes with the examples), we can
82 # get some more information about it.
83 if isinstance(section
, SymbolTableSection
):
84 num_symbols
= section
.num_symbols()
85 print(" It's a symbol section with %s symbols" % num_symbols
)
86 print(" The name of the last symbol in the section is: %s" % (
87 bytes2str(section
.get_symbol(num_symbols
- 1).name
)))
90 if __name__
== '__main__':
91 for filename
in sys
.argv
[1:]:
92 process_file(filename
)