eliben / pyelftools

Parsing ELF and DWARF in Python
Other
2.01k stars 510 forks source link

Unable to initialize ELFFile with arm sample #393

Closed 0ssigeno closed 6 months ago

0ssigeno commented 2 years ago

Hi guys!

I was using pyelftools to analyze some malware and I encountered an error with some ARM samples:

When calling

with open("/home/ossigeno/Downloads/vt_56bebd4b9558bb9f539022bd2c5e40aecfa8d59c09784de61d1ba92766e2a30b","rb") as f:
    ELFFile(f)

The tracelog error raised is the following:

Traceback (most recent call last):
  File "/home/ossigeno/Tools/pyelftools/elftools/construct/core.py", line 351, in _parse
    return self.packer.unpack(_read_stream(stream, self.length))[0]
  File "/home/ossigeno/Tools/pyelftools/elftools/construct/core.py", line 293, in _read_stream
    raise FieldError("expected %d, found %d" % (length, len(data)))
elftools.construct.core.FieldError: expected 4, found 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ossigeno/Tools/pyelftools/elftools/common/utils.py", line 40, in struct_parse
    return struct.parse_stream(stream)
  File "/home/ossigeno/Tools/pyelftools/elftools/construct/core.py", line 190, in parse_stream
    return self._parse(stream, Container())
  File "/home/ossigeno/Tools/pyelftools/elftools/construct/core.py", line 647, in _parse
    subobj = sc._parse(stream, context)
  File "/home/ossigeno/Tools/pyelftools/elftools/construct/core.py", line 353, in _parse
    raise FieldError(ex)
elftools.construct.core.FieldError: expected 4, found 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/home/ossigeno/Tools/pyelftools/elftools/elf/elffile.py", line 88, in __init__
    self._get_section_header_stringtable()
  File "/home/ossigeno/Tools/pyelftools/elftools/elf/elffile.py", line 692, in _get_section_header_stringtable
    header=self._get_section_header(stringtable_section_num),
  File "/home/ossigeno/Tools/pyelftools/elftools/elf/elffile.py", line 550, in _get_section_header
    return struct_parse(
  File "/home/ossigeno/Tools/pyelftools/elftools/common/utils.py", line 42, in struct_parse
    raise ELFParseError(str(e))
elftools.common.exceptions.ELFParseError: expected 4, found 0

The error is raised with both the current pypi release, and the master branch. I'm sorry to be unable to provide more information about this, but I have very low knowledge about the internals of the project.

sevaa commented 6 months ago

@0ssigeno is still still an issue?

0ssigeno commented 6 months ago

Hi! Sorry for the late answer. I tried again with the sample in the code of my first message, and the error seems to be still present :(

sevaa commented 6 months ago

We would need a copy of the offending binary to take a closer look.

That said, I won't be surprised if a piece of malware is deliberately malformed in the way that allows it to load but complicates parsing. While the problem of making sense of malware files is legitimate, I don't think it's reasonable to expect pyelftools to work with those correctly. Parsers, as a rule, throw exceptions on those.

0ssigeno commented 6 months ago

Absolutely agree that, if the samples have their headers actually malformed pyelftools should not work. I opened this issue because, unfortunately, I don't know enough about elf headers or how pyelftools works to double check if these sample should not work with pyelftools or if there is a parsing error with the library itself.

If you are interested on test it yourself to see whether is a real error or not, you should be able to download one of the offending sample from malware bazaar without the need of a registered account. Take all precautions necessary, because it is a malware.

sevaa commented 6 months ago

Tried both of those (note: on Windows you have to switch off OS level real time protection, or the system will remove the file the moment you try to touch it). They look malformed to me - the very first section seems to be beyond the file size. GNU readelf seems to agree:

$ readelf -S mw.elf There are 10 section headers, starting at offset 0xebc8: readelf: Error: Reading 400 bytes extends past end of file for section headers

Pyelftools seems to be working as expected. This is not an issue with pyelftools, except maybe in the very narrow sense that the exception message is somewhat misleading (it complains about a missing string table; the error occurs even before that).

0ssigeno commented 6 months ago

Oki, nothing that we can do if they are malformed, I have to agree with you.

A more "verbose" error would be nice, but I can argue that the implementation time for changing the error message when the header is malformed is overkill for this.

Thank you for your time, I think that we can close this issue!

sevaa commented 6 months ago

I can't close the issue. You can.

0ssigeno commented 5 months ago

Wops, thought you were admin in the repo, and wanted to double check before actually closing it