Layers: Use ctypes for snappy support

This commit is contained in:
Mike Auty
2023-02-18 21:15:43 +00:00
parent 4734a3d1f8
commit 471b19b037
3 changed files with 28 additions and 15 deletions
-4
View File
@@ -20,7 +20,3 @@ jsonschema>=2.3.0
# This is required for memory acquisition via leechcore/pcileech.
leechcorepyc>=2.4.0
# This is required for analyzing Linux samples compressed using AVMLs native
# compression format. It is not required for AVML's standard LiME compression.
python-snappy==0.6.0
-4
View File
@@ -16,7 +16,3 @@ pycryptodome
# This is required for memory acquisition via leechcore/pcileech.
leechcorepyc>=2.4.0
# This is required for analyzing Linux samples compressed using AVMLs native
# compression format. It is not required for AVML's standard LiME compression.
python-snappy==0.6.0
+28 -7
View File
@@ -6,6 +6,7 @@
The user of the file doesn't have to worry about the compression,
but random access is not allowed."""
import ctypes
import logging
import struct
from typing import Tuple, List, Optional
@@ -16,13 +17,35 @@ from volatility3.framework.layers import segmented
vollog = logging.getLogger(__name__)
try:
import snappy
from ctypes import cdll
# TODO: Find library for windows if needed
lib_snappy = cdll.LoadLibrary("libsnappy.so.1")
__snappy_uncompress = lib_snappy.snappy_uncompress
__snappy_uncompressed_length = lib_snappy.snappy_uncompressed_length
HAS_SNAPPY = True
except ImportError:
except OSError:
HAS_SNAPPY = False
class SnappyException(Exception):
pass
def uncompress(s):
"""Uncompress a snappy compressed string."""
ulen = ctypes.c_int(0)
cresult = __snappy_uncompressed_length(s, len(s), ctypes.byref(ulen))
if cresult != 0:
raise SnappyException(f"Error in snappy_uncompressed_length: {cresult}")
ubuf = ctypes.create_string_buffer(ulen.value)
__snappy_uncompress(s, len(s), ubuf, ctypes.byref(ulen))
if cresult != 0:
raise SnappyException(f"Error in snappy_uncompress: {cresult}")
return ubuf.raw
class AVMLLayer(segmented.NonLinearlySegmentedLayer):
"""A Lime format TranslationLayer.
@@ -44,9 +67,7 @@ class AVMLLayer(segmented.NonLinearlySegmentedLayer):
if magic not in [0x4C4D5641] or version != 2:
raise exceptions.LayerException("File not completely in AVML format")
if not HAS_SNAPPY:
vollog.warning(
"AVML file detected, but snappy python library not installed"
)
vollog.warning("AVML file detected, but snappy library could not be found")
raise exceptions.LayerException(
"AVML format dependencies not satisfied (snappy)"
)
@@ -131,7 +152,7 @@ class AVMLLayer(segmented.NonLinearlySegmentedLayer):
]
if frame_type == 0x00:
# Compressed data
frame_data = snappy.decompress(frame_data)
frame_data = uncompress(frame_data)
# TODO: Verify CRC
segments.append(
(
@@ -156,7 +177,7 @@ class AVMLLayer(segmented.NonLinearlySegmentedLayer):
) -> bytes:
start_offset, _, _, _ = self._find_segment(offset)
if self._compressed[mapped_offset]:
decoded_data = snappy.decompress(data)
decoded_data = uncompress(data)
else:
decoded_data = data
decoded_data = decoded_data[offset - start_offset :]