From d545ac92ba3d8275abf9fef3b7618b84e30151e7 Mon Sep 17 00:00:00 2001 From: David McDonald Date: Thu, 13 Feb 2025 10:49:01 -0600 Subject: [PATCH] Windows FileScan: Add physical offset optional requirement This adds an optional boolean requirement that will allow the plugin to return physical offsets as an alternative to virtual offsets. --- .../framework/plugins/windows/filescan.py | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/volatility3/framework/plugins/windows/filescan.py b/volatility3/framework/plugins/windows/filescan.py index 82566361d..4d08e637a 100644 --- a/volatility3/framework/plugins/windows/filescan.py +++ b/volatility3/framework/plugins/windows/filescan.py @@ -4,7 +4,7 @@ from typing import Iterable -from volatility3.framework import renderers, interfaces, exceptions +from volatility3.framework import exceptions, interfaces, layers, renderers from volatility3.framework.configuration import requirements from volatility3.framework.renderers import format_hints from volatility3.plugins.windows import poolscanner @@ -14,7 +14,7 @@ class FileScan(interfaces.plugins.PluginInterface): """Scans for file objects present in a particular windows memory image.""" _required_framework_version = (2, 0, 0) - _version = (1, 0, 1) + _version = (1, 1, 1) @classmethod def get_requirements(cls): @@ -27,6 +27,12 @@ class FileScan(interfaces.plugins.PluginInterface): requirements.PluginRequirement( name="poolscanner", plugin=poolscanner.PoolScanner, version=(1, 0, 0) ), + requirements.BooleanRequirement( + name="physical", + description="Display physical offset instead of virtual", + default=False, + optional=True, + ), ] @classmethod @@ -60,6 +66,13 @@ class FileScan(interfaces.plugins.PluginInterface): def _generator(self): kernel = self.context.modules[self.config["kernel"]] + if self.config["physical"]: + physical_layer = self.context.layers[kernel.layer_name] + if not isinstance(physical_layer, layers.intel.Intel): + raise TypeError("Primary layer is not an intel layer") + else: + physical_layer = None + for fileobj in self.scan_files( self.context, kernel.layer_name, kernel.symbol_table_name ): @@ -68,7 +81,14 @@ class FileScan(interfaces.plugins.PluginInterface): except exceptions.InvalidAddressException: continue - yield (0, (format_hints.Hex(fileobj.vol.offset), file_name)) + if physical_layer: + (_, _, offset, _, _) = list( + physical_layer.mapping(offset=fileobj.vol.offset, length=0) + )[0] + else: + offset = fileobj.vol.offset + + yield (0, (format_hints.Hex(offset), file_name)) def run(self): return renderers.TreeGrid(