dnfile icon indicating copy to clipboard operation
dnfile copied to clipboard

IndexError in read_compressed_int (utils.py)

Open gdesmar opened this issue 1 year ago • 3 comments

I was wondering if you'd be interested by this error, caused by this file. I found it using CAPA, with dnfile 0.14.1, but it also triggers on 0.15.0.

>>> import dnfile
>>> pe = dnfile.dnPE("e94f7c475e7db0691a2698b5dd349c2b412ffddafa7a3ff85785cbd5ac144fcb")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../dnfile/__init__.py", line 64, in __init__
    super().__init__(name, data, fast_load)
  File ".../pefile.py", line 2895, in __init__
    self.__parse__(name, data, fast_load)
  File ".../dnfile/__init__.py", line 132, in __parse__
    super().__parse__(fname, data, fast_load)
  File ".../pefile.py", line 3328, in __parse__
    self.full_load()
  File ".../pefile.py", line 3439, in full_load
    self.parse_data_directories()
  File ".../dnfile/__init__.py", line 178, in parse_data_directories
    value = entry[1](dir_entry.VirtualAddress, dir_entry.Size)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../dnfile/__init__.py", line 221, in parse_clr_structure
    return ClrData(self, rva, size, self.clr_lazy_load)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../dnfile/__init__.py", line 526, in __init__
    self._init_resources(pe)
  File ".../dnfile/__init__.py", line 574, in _init_resources
    rsrc.parse()
  File ".../dnfile/resource.py", line 289, in parse
    rs.parse()
  File ".../dnfile/resource.py", line 433, in parse
    rsrc_factory.read_rsrc_data_v1(self._data, e_data_offset, self.resource_types, e)
  File ".../dnfile/resource.py", line 113, in read_rsrc_data_v1
    d, v = self.type_str_to_type(entry.type_name, data, offset)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../dnfile/resource.py", line 166, in type_str_to_type
    final_bytes, n = self.read_serialized_data(data, offset)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../dnfile/resource.py", line 72, in read_serialized_data
    x = utils.read_compressed_int(data[offset:offset + 4])
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../dnfile/utils.py", line 46, in read_compressed_int
    value |= data[1]
             ~~~~^^^
IndexError: index out of range

The file doesn't look to be too badly corrupted, but I may be wrong. 🙂

gdesmar avatar Mar 28 '24 18:03 gdesmar

@gdesmar I just pushed a commit that should fix that IndexError. I do not have access to the file, so can you test with it and paste the output here? It should give a rsrcFormatError now but with more useful context.

malwarefrank avatar Apr 03 '24 23:04 malwarefrank

Here is the current output:

>>> import dnfile
>>> pe = dnfile.dnPE("e94f7c475e7db0691a2698b5dd349c2b412ffddafa7a3ff85785cbd5ac144fcb")
invalid compressed int: leading byte: 0xbc
>>> pe
<dnfile.dnPE object at 0x7f1c796fdc90>
>>> pe.verify_checksum()
True

I do not know where the rsrcFormatError should be found.

CAPA's currently locked at 0.14.1 and looking into CAPA's code deeper, it doesn't look compatible with dnfile.mdtable.MemberRefRow's .Name not being straight strings anymore, but dnfile.stream.HeapItemString (using .startswith()). I'm assuming this is a change between 0.14.1 and 0.15.0.

If you would like for me to execute anything else on the resulting dnPE, I will gladly give you the results. Besides that, I assume that we can close this issue. This can always be referred to later if anyone digs deeper into it and finds more issues. Thank you for your time!

gdesmar avatar Apr 04 '24 01:04 gdesmar

Hmm... I should make that a more helpful warning. One of the .NET resources may be malformed. I'll see if I can get a copy of that file and troubleshoot myself some more. At the very least, it should be parsing most of it except for that possibly malformed resource.

malwarefrank avatar Apr 05 '24 03:04 malwarefrank