From 449a1937911229a779fc85e2c675fc60a2851298 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Mon, 9 Mar 2026 21:34:28 +0000 Subject: [PATCH] Add in Zstd support (only present in >=python-3.14) --- volatility3/framework/layers/resources.py | 28 ++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/volatility3/framework/layers/resources.py b/volatility3/framework/layers/resources.py index 66fb617af..0e14a0032 100644 --- a/volatility3/framework/layers/resources.py +++ b/volatility3/framework/layers/resources.py @@ -14,7 +14,7 @@ import sys import urllib.parse import urllib.request import zipfile -from typing import Any, IO, List, Optional +from typing import IO, Any, List, Optional from urllib import error from volatility3 import framework @@ -27,6 +27,13 @@ try: except ImportError: HAS_MAGIC = False +try: + import zstd + + ZSTD_SUPPORTED = True +except ImportError: + ZSTD_SUPPORTED = False + try: # Import so that the handler is found by the framework.class_subclasses callc from smb import SMBHandler as SMBHandler # lgtm [py/unused-import] @@ -232,21 +239,26 @@ class ResourceAccessor: # Only file's python has magic.detect_from_fobj if detected: + inside_compressed_file = False if detected.mime_type == "application/x-xz": curfile = cascadeCloseFile( lzma.LZMAFile(curfile, mode), curfile ) + inside_compressed_file = True elif detected.mime_type == "application/x-bzip2": curfile = cascadeCloseFile(bz2.BZ2File(curfile, mode), curfile) + inside_compressed_file = True elif detected.mime_type == "application/x-gzip": curfile = cascadeCloseFile( gzip.GzipFile(fileobj=curfile, mode=mode), curfile ) - if detected.mime_type in [ - "application/x-xz", - "application/x-bzip2", - "application/x-gzip", - ]: + inside_compressed_file = True + elif detected.mime_type == "application/zstd" and ZSTD_SUPPORTED: + curfile = cascadeCloseFile( + zstd.ZstdFile(fileobj=curfile, mode=mode), curfile + ) + inside_compressed_file = True + if inside_compressed_file: # Read and rewind to ensure we're inside any compressed file layers curfile.read(1) curfile.seek(0) @@ -272,6 +284,10 @@ class ResourceAccessor: curfile = cascadeCloseFile( gzip.GzipFile(fileobj=curfile, mode=mode), curfile ) + elif extension == "zstd" and ZSTD_SUPPORTED: + curfile = cascadeCloseFile( + zstd.ZstdFile(fileobj=curfile, mode=mode), curfile + ) else: stop = True