# Eli Bendersky (eliben@gmail.com)\r
# This code is in the public domain\r
#-------------------------------------------------------------------------------\r
-\r
class ELFError(Exception): \r
pass
\r
# Eli Bendersky (eliben@gmail.com)\r
# This code is in the public domain\r
#-------------------------------------------------------------------------------\r
-\r
class SHN_INDICES(object):\r
""" Special section indices
"""\r
from ..common.utils import struct_parse\r
from ..construct import ConstructError\r
from .structs import ELFStructs\r
-from .sections import Section, StringTableSection\r
+from .sections import Section, StringTableSection, SymbolTableSection\r
from .segments import Segment\r
\r
\r
return self['e_shnum']\r
\r
def get_section(self, n):
- """ Get the section at index #n from the file (Section object)
+ """ Get the section at index #n from the file (Section object or a\r
+ subclass)
"""\r
section_header = self._get_section_header(n)\r
- name = self._get_section_name(section_header)\r
- return Section(section_header, name, self.stream)\r
+ return self._make_section(section_header)\r
\r
def iter_sections(self):
""" Yield all the sections in the file
name_offset = section_header['sh_name']\r
return self._file_stringtable_section.get_string(name_offset)\r
\r
+ def _make_section(self, section_header):
+ """ Create a section object of the appropriate type
+ """\r
+ name = self._get_section_name(section_header)\r
+ sectype = section_header['sh_type']\r
+ \r
+ if sectype == 'SHT_STRTAB':\r
+ return StringTableSection(section_header, name, self.stream)\r
+ elif sectype in ('SHT_SYMTAB', 'SHT_DYNSYM'):\r
+ return self._make_symbol_table_section(section_header, name)\r
+ else:\r
+ return Section(section_header, name, self.stream)\r
+\r
+ def _make_symbol_table_section(self, section_header, name):
+ """ Create a SymbolTableSection
+ """\r
+ linked_strtab_index = section_header['sh_link']\r
+ strtab_section = self.get_section(linked_strtab_index)\r
+ return SymbolTableSection(\r
+ section_header, name, self.stream,\r
+ stringtable=strtab_section)\r
+\r
def _get_segment_header(self, n):
""" Find the header of segment #n, parse it and return the struct
"""\r
# This code is in the public domain\r
#-------------------------------------------------------------------------------\r
from ..construct import CString\r
+from ..common.utils import struct_parse\r
\r
\r
-class Section(object):
+class Section(object):\r
+ """ Base class for ELF sections. Also used for all sections types that have\r
+ no special functionality.\r
+ \r
+ Allows dictionary-like access to the section header. For example:\r
+ > sec = Section(...)\r
+ > sec['sh_type'] # section type\r
+ """
def __init__(self, header, name, stream):
self.header = header\r
self.name = name\r
return self.header[name]\r
\r
\r
-class StringTableSection(Section):
+class StringTableSection(Section):\r
+ """ ELF string table section.
+ """
def __init__(self, header, name, stream):
super(StringTableSection, self).__init__(header, name, stream)\r
\r
""" Get the string stored at the given offset in this string table.
"""\r
table_offset = self['sh_offset']\r
- self.stream.seek(table_offset + offset)\r
- return CString('').parse_stream(self.stream)
+ return struct_parse(\r
+ CString(''),\r
+ self.stream,\r
+ stream_pos=table_offset + offset)\r
\r
\r
+class SymbolTableSection(Section):\r
+ """ ELF symbol table section. Has an associated StringTableSection that's\r
+ passed in the constructor.
+ """
+ def __init__(self, header, name, stream, stringtable):\r
+ super(SymbolTableSection, self).__init__(header, name, stream)
+ self.stringtable = stringtable\r
\r
-
+\r
# Eli Bendersky (eliben@gmail.com)\r
# This code is in the public domain\r
#-------------------------------------------------------------------------------\r
-\r
from ..construct import (\r
UBInt8, UBInt16, UBInt32, UBInt64,\r
ULInt8, ULInt16, ULInt32, ULInt64,\r
import sys\r
from elftools.elf.structs import ELFStructs\r
from elftools.elf.elffile import ELFFile\r
+from elftools.elf.sections import *\r
\r
# read a little-endian, 64-bit file\r
es = ELFStructs(True, 64)\r
print '===> %s segments!' % efile.num_segments()\r
\r
for sec in efile.iter_sections():\r
- print sec.name\r
+ print type(sec), sec.name\r
+ if isinstance(sec, SymbolTableSection):\r
+ print ' linked string table:', sec.stringtable.name\r
\r
for seg in efile.iter_segments():\r
print seg['p_type'], seg['p_offset']\r
\r
+\r
#~ print 'num', efile.num_sections()\r
#~ sec = efile.get_section(39)\r
#~ print sec.header\r