PAGESIZE = 4096
from ..common.py3compat import BytesIO
-from ..common.exceptions import ELFError
+from ..common.exceptions import ELFError, ELFParseError
from ..common.utils import struct_parse, elf_assert
from .structs import ELFStructs
from .sections import (
"""
def __init__(self, stream, stream_loader=None):
self.stream = stream
+ self.stream.seek(0, io.SEEK_END)
+ self.stream_len = self.stream.tell()
+
self._identify_file()
self.structs = ELFStructs(
little_endian=self.little_endian,
def _get_section_header(self, n):
""" Find the header of section #n, parse it and return the struct
"""
+
+ stream_pos = self._section_offset(n)
+ if stream_pos > self.stream_len:
+ return None
+
return struct_parse(
self.structs.Elf_Shdr,
self.stream,
- stream_pos=self._section_offset(n))
+ stream_pos=stream_pos)
def _get_section_name(self, section_header):
""" Given a section header, find this section's name in the file's
string table
"""
+ if self._section_header_stringtable is None:
+ raise ELFParseError("String Table not found")
+
name_offset = section_header['sh_name']
return self._section_header_stringtable.get_string(name_offset)
table.
"""
stringtable_section_num = self.get_shstrndx()
+
+ stringtable_section_header = self._get_section_header(stringtable_section_num)
+ if stringtable_section_header is None:
+ return None
+
return StringTableSection(
- header=self._get_section_header(stringtable_section_num),
+ header=stringtable_section_header,
name='',
elffile=self)
--- /dev/null
+"""
+Test that elftools does not fail to load corrupted ELF files
+"""
+import unittest
+import os
+
+from elftools.elf.elffile import ELFFile
+from elftools.common.exceptions import ELFParseError
+
+
+class TestCorruptFile(unittest.TestCase):
+ def test_elffile_init(self):
+ """ Test that ELFFile does not crash when parsing an ELF file with corrupt e_shoff and/or e_shnum
+ """
+ filepath = os.path.join('test', 'testfiles_for_unittests', 'corrupt_sh.elf')
+ with open(filepath, 'rb') as f:
+ elf = None
+
+ try:
+ elf = ELFFile(f)
+ except ELFParseError:
+ pass
+
+ self.assertIsInstance(elf, ELFFile, "ELFFile initialization should have detected the out of bounds read")
+
+
+if __name__ == '__main__':
+ unittest.main()