From 1d20e6575908e118ad71746ff9d64b6cd5d23d9f Mon Sep 17 00:00:00 2001 From: David McDonald Date: Thu, 3 Apr 2025 17:39:14 -0500 Subject: [PATCH] Add versioning to MFT extension classes --- .../framework/plugins/windows/mftscan.py | 15 ++++++++++++ .../symbols/windows/extensions/mft.py | 24 ++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/volatility3/framework/plugins/windows/mftscan.py b/volatility3/framework/plugins/windows/mftscan.py index eacd43b8a..7df895f15 100644 --- a/volatility3/framework/plugins/windows/mftscan.py +++ b/volatility3/framework/plugins/windows/mftscan.py @@ -49,6 +49,21 @@ class MFTScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): component=timeliner.TimeLinerInterface, version=(1, 0, 0), ), + requirements.VersionRequirement( + name="mft_entry", + component=mft.MFTEntry, + version=(1, 0, 0), + ), + requirements.VersionRequirement( + name="mft_filename", + component=mft.MFTFileName, + version=(1, 0, 0), + ), + requirements.VersionRequirement( + name="mft_attribute", + component=mft.MFTAttribute, + version=(1, 0, 0), + ), requirements.VersionRequirement( name="yarascanner", component=yarascan.YaraScanner, version=(2, 1, 0) ), diff --git a/volatility3/framework/symbols/windows/extensions/mft.py b/volatility3/framework/symbols/windows/extensions/mft.py index 4c5be81ee..32261c4ff 100644 --- a/volatility3/framework/symbols/windows/extensions/mft.py +++ b/volatility3/framework/symbols/windows/extensions/mft.py @@ -5,14 +5,20 @@ import logging from typing import Dict, Iterator, List, Optional, Tuple +from volatility3 import framework from volatility3.framework import constants, exceptions, interfaces, objects vollog = logging.getLogger(__name__) -class MFTEntry(objects.StructType): +class MFTEntry(objects.StructType, interfaces.configuration.VersionableInterface): """This represents the base MFT Record""" + _version = (1, 0, 0) + _required_framework_version = (2, 26, 0) + + framework.require_interface_version(*_required_framework_version) + def __init__( self, context: interfaces.context.ContextInterface, @@ -144,9 +150,15 @@ class MFTEntry(objects.StructType): yield attr -class MFTFileName(objects.StructType): +class MFTFileName(objects.StructType, interfaces.configuration.VersionableInterface): """This represents an MFT $FILE_NAME Attribute""" + _version = (1, 0, 0) + + _required_framework_version = (2, 26, 0) + + framework.require_interface_version(*_required_framework_version) + def get_full_name(self) -> objects.String: output = self.Name.cast( "string", encoding="utf16", max_length=self.NameLength * 2, errors="replace" @@ -154,9 +166,15 @@ class MFTFileName(objects.StructType): return output -class MFTAttribute(objects.StructType): +class MFTAttribute(objects.StructType, interfaces.configuration.VersionableInterface): """This represents an MFT ATTRIBUTE""" + _version = (1, 0, 0) + + _required_framework_version = (2, 26, 0) + + framework.require_interface_version(*_required_framework_version) + def get_resident_filename(self) -> Optional[objects.String]: # 4MB chosen as cutoff instead of 4KB to allow for recovery from format /L created file systems # Length as 512 as its 256*2, which is the maximum size for an entire file path, so this is even generous