From 4492da0263d866ed36d0e6f0b197789896d347b2 Mon Sep 17 00:00:00 2001 From: David McDonald Date: Thu, 3 Apr 2025 10:38:13 -0500 Subject: [PATCH] Create attribute iterator method Moves logic for iterating through `MFTEntry` attributes into a new `attributes()` method on the extension class. --- .../framework/plugins/windows/mftscan.py | 28 ++--------------- .../symbols/windows/extensions/mft.py | 31 ++++++++++++++++++- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/volatility3/framework/plugins/windows/mftscan.py b/volatility3/framework/plugins/windows/mftscan.py index 0c204ac1f..78312f284 100644 --- a/volatility3/framework/plugins/windows/mftscan.py +++ b/volatility3/framework/plugins/windows/mftscan.py @@ -114,7 +114,6 @@ class MFTScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): # get each of the individual Field Sets mft_object_type_name = symbol_table + constants.BANG + "MFT_ENTRY" - attribute_object_type_name = symbol_table + constants.BANG + "ATTRIBUTE" record_map: DefaultDict[str, MFTRecord] = DefaultDict(MFTRecord) @@ -127,30 +126,9 @@ class MFTScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): mft_object_type_name, offset=offset, layer_name=layer.name ) - # We will update this on each pass in the next loop and use it as the new offset. - attr_base_offset = mft_record.FirstAttrOffset - attr: mft.MFTAttribute = context.object( - attribute_object_type_name, - offset=offset + attr_base_offset, - layer_name=layer.name, - ) - - # There is no field that has a count of Attributes - # Keep Attempting to read attributes until we get an invalid attr_header.AttrType - while attr.Attr_Header.AttrType.is_valid_choice: - yield from attr_callback(record_map, mft_record, attr, symbol_table) - - # If there's no advancement the loop will never end, so break it now - if attr.Attr_Header.Length == 0: - break - - # Update the base offset to point to the next attribute - attr_base_offset += attr.Attr_Header.Length - # Get the next attribute - attr: mft.MFTAttribute = context.object( - attribute_object_type_name, - offset=offset + attr_base_offset, - layer_name=layer.name, + for attribute in mft_record.attributes(symbol_table): + yield from attr_callback( + record_map, mft_record, attribute, symbol_table ) @classmethod diff --git a/volatility3/framework/symbols/windows/extensions/mft.py b/volatility3/framework/symbols/windows/extensions/mft.py index 9dd7f1a6a..4e1140e25 100644 --- a/volatility3/framework/symbols/windows/extensions/mft.py +++ b/volatility3/framework/symbols/windows/extensions/mft.py @@ -2,7 +2,7 @@ # which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 # -from typing import Optional +from typing import Optional, Iterator from volatility3.framework import objects, constants, exceptions @@ -14,6 +14,35 @@ class MFTEntry(objects.StructType): signature = self.Signature.cast("string", max_length=4, encoding="latin-1") return signature + def attributes(self, symbol_table_name: str) -> Iterator["MFTAttribute"]: + # We will update this on each pass in the next loop and use it as the new offset. + attr_base_offset = self.FirstAttrOffset + attribute_object_type_name = symbol_table_name + constants.BANG + "ATTRIBUTE" + + attr: MFTAttribute = self._context.object( + attribute_object_type_name, + offset=self.vol.offset + attr_base_offset, + layer_name=self.vol.layer_name, + ) + + # There is no field that has a count of Attributes + # Keep Attempting to read attributes until we get an invalid attr_header.AttrType + while attr.Attr_Header.AttrType.is_valid_choice: + yield attr + + # If there's no advancement the loop will never end, so break it now + if attr.Attr_Header.Length == 0: + break + + # Update the base offset to point to the next attribute + attr_base_offset += attr.Attr_Header.Length + # Get the next attribute + attr: MFTAttribute = self._context.object( + attribute_object_type_name, + offset=self.vol.offset + attr_base_offset, + layer_name=self.vol.layer_name, + ) + class MFTFileName(objects.StructType): """This represents an MFT $FILE_NAME Attribute"""