def struct_parse(struct, stream, stream_pos=None):
- """ Convenience function for using the given struct to parse a stream (at
- its current location).
+ """ Convenience function for using the given struct to parse a stream.
If stream_pos is provided, the stream is seeked to this position before
- the parsing is done.
- Wraps the error thrown by construct with our own error.
+ the parsing is done. Otherwise, the current position of the stream is
+ used.
+ Wraps the error thrown by construct with ELFParseError.
"""
try:
if stream_pos is not None:
from ..construct import ConstructError
from .structs import ELFStructs
from .sections import Section, StringTableSection, SymbolTableSection
-from .segments import Segment
+from .segments import Segment, InterpSegment
class ELFFile(object):
""" Get the segment at index #n from the file (Segment object)
"""
segment_header = self._get_segment_header(n)
- return Segment(segment_header, self.stream)
+ return self._make_segment(segment_header)
def iter_segments(self):
""" Yield all the segments in the file
"""
return self['e_phoff'] + n * self['e_phentsize']
+ def _make_segment(self, segment_header):
+ """ Create a Segment object of the appropriate type
+ """
+ segtype = segment_header['p_type']
+ if segtype == 'PT_INTERP':
+ return InterpSegment(segment_header, self.stream)
+ else:
+ return Segment(segment_header, self.stream)
+
def _get_section_header(self, n):
""" Find the header of section #n, parse it and return the struct
"""
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
+from ..construct import CString
+from ..common.utils import struct_parse
+
class Segment(object):
def __init__(self, header, stream):
"""
return self.header[name]
+
+class InterpSegment(Segment):
+ """ INTERP segment. Knows how to obtain the path to the interpreter used
+ for this ELF file.
+ """
+ def __init__(self, header, stream):
+ super(InterpSegment, self).__init__(header, stream)
+
+ def get_interp_name(self):
+ """ Obtain the interpreter path used for this ELF file.
+ """
+ path_offset = self['p_offset']
+ return struct_parse(
+ CString(''),
+ self.stream,
+ stream_pos=path_offset)
+
+
from elftools.common.exceptions import ELFError
from elftools.elf.elffile import ELFFile
+from elftools.elf.segments import InterpSegment
from elftools.elf.descriptions import (
describe_ei_class, describe_ei_data, describe_ei_version,
describe_ei_osabi, describe_e_type, describe_e_machine,
describe_p_flags(segment['p_flags']),
self._format_hex(segment['p_align'])))
+ if isinstance(segment, InterpSegment):
+ self._emitline(' [Requesting program interpreter: %s]' %
+ segment.get_interp_name())
+
print ' linked string table:', sec.stringtable.name
for seg in efile.iter_segments():
- print seg['p_type'], seg['p_offset']
+ print type(seg), seg['p_type'], seg['p_offset']
for sec in efile.iter_sections():
if isinstance(sec, SymbolTableSection):