From 7289f7dc70b77004bbf0c48d14ead436cfa925ff Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Mon, 10 Mar 2025 03:27:56 +0000 Subject: [PATCH 1/2] Ensure that new symbol tables are only created when needed. Avoid name collisions leading to inconsistent behaviour. Make API for symbol table acquisition sane. --- .../framework/plugins/windows/modscan.py | 2 +- .../framework/plugins/windows/netscan.py | 2 +- .../framework/plugins/windows/poolscanner.py | 76 ++++++++++--------- .../framework/plugins/windows/psscan.py | 2 +- .../framework/plugins/windows/symlinkscan.py | 2 +- .../plugins/windows/windowstations.py | 2 +- 6 files changed, 45 insertions(+), 41 deletions(-) diff --git a/volatility3/framework/plugins/windows/modscan.py b/volatility3/framework/plugins/windows/modscan.py index 7330b2cb4..667fadd11 100644 --- a/volatility3/framework/plugins/windows/modscan.py +++ b/volatility3/framework/plugins/windows/modscan.py @@ -32,7 +32,7 @@ class ModScan(modules.Modules): architectures=["Intel32", "Intel64"], ), requirements.VersionRequirement( - name="poolscanner", component=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", component=poolscanner.PoolScanner, version=(3, 0, 0) ), requirements.VersionRequirement( name="modules", component=modules.Modules, version=(3, 0, 0) diff --git a/volatility3/framework/plugins/windows/netscan.py b/volatility3/framework/plugins/windows/netscan.py index 0c8523cce..1ab748864 100644 --- a/volatility3/framework/plugins/windows/netscan.py +++ b/volatility3/framework/plugins/windows/netscan.py @@ -34,7 +34,7 @@ class NetScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): architectures=["Intel32", "Intel64"], ), requirements.VersionRequirement( - name="poolscanner", component=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", component=poolscanner.PoolScanner, version=(3, 0, 0) ), requirements.VersionRequirement( name="info", component=info.Info, version=(2, 0, 0) diff --git a/volatility3/framework/plugins/windows/poolscanner.py b/volatility3/framework/plugins/windows/poolscanner.py index 5e75d9bbb..7dd6821b8 100644 --- a/volatility3/framework/plugins/windows/poolscanner.py +++ b/volatility3/framework/plugins/windows/poolscanner.py @@ -129,7 +129,7 @@ class PoolScanner(plugins.PluginInterface): """A generic pool scanner plugin.""" _required_framework_version = (2, 0, 0) - _version = (2, 0, 0) + _version = (3, 0, 0) @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: @@ -423,6 +423,7 @@ class PoolScanner(plugins.PluginInterface): # scan in the main kernel layer for the object(s) for constraint, header in cls.pool_scan( context, + kernel_module_name, scan_layer, object_symbol_table_name, constraints, @@ -501,6 +502,7 @@ class PoolScanner(plugins.PluginInterface): def pool_scan( cls, context: interfaces.context.ContextInterface, + kernel_module_name: str, layer_name: str, symbol_table: str, pool_constraints: List[PoolConstraint], @@ -534,8 +536,16 @@ class PoolScanner(plugins.PluginInterface): ) constraint_lookup[constraint.tag] = constraint - pool_header_table_name = cls.get_pool_header_table(context, symbol_table) - module = context.module(pool_header_table_name, layer_name, offset=0) + kernel = context.modules[kernel_module_name] + + if kernel.has_type("_POOL_HEADER"): + pool_header_table_name = kernel.symbol_table_name + else: + pool_header_table_name = cls.get_pool_header_table(context, symbol_table) + + module = context.module( + pool_header_table_name, layer_name, offset=kernel.offset + ) # Run the scan locating the offsets of a particular tag layer = context.layers[layer_name] @@ -553,43 +563,37 @@ class PoolScanner(plugins.PluginInterface): context: The context that the symbol tables does (or will) reside in symbol_table: The expected symbol_table to contain the _POOL_HEADER type """ - # Setup the pool header and offset differential - try: - context.symbol_space.get_type( - symbol_table + constants.BANG + "_POOL_HEADER" - ) - table_name = symbol_table - except exceptions.SymbolError: - # We have to manually load a symbol table + # We have to manually load a symbol table - if symbols.symbol_table_is_64bit( - context=context, symbol_table_name=symbol_table - ): - is_win_7 = versions.is_windows_7(context, symbol_table) - if is_win_7: - pool_header_json_filename = "poolheader-x64-win7" - else: - pool_header_json_filename = "poolheader-x64" + if symbols.symbol_table_is_64bit( + context=context, symbol_table_name=symbol_table + ): + is_win_7 = versions.is_windows_7(context, symbol_table) + if is_win_7: + pool_header_json_filename = "poolheader-x64-win7" else: - pool_header_json_filename = "poolheader-x86" + pool_header_json_filename = "poolheader-x64" + else: + pool_header_json_filename = "poolheader-x86" - # set the class_type to match the normal WindowsKernelIntermedSymbols - is_vista_or_later = versions.is_vista_or_later(context, symbol_table) - if is_vista_or_later: - class_type = extensions.pool.POOL_HEADER_VISTA - else: - class_type = extensions.pool.POOL_HEADER + # set the class_type to match the normal WindowsKernelIntermedSymbols + is_vista_or_later = versions.is_vista_or_later(context, symbol_table) + if is_vista_or_later: + class_type = extensions.pool.POOL_HEADER_VISTA + else: + class_type = extensions.pool.POOL_HEADER + + table_name = intermed.IntermediateSymbolTable.create( + context=context, + config_path=configuration.path_join( + context.symbol_space[symbol_table].config_path, "poolheader" + ), + sub_path="windows", + filename=pool_header_json_filename, + table_mapping={"nt_symbols": symbol_table}, + class_types={"_POOL_HEADER": class_type}, + ) - table_name = intermed.IntermediateSymbolTable.create( - context=context, - config_path=configuration.path_join( - context.symbol_space[symbol_table].config_path, "poolheader" - ), - sub_path="windows", - filename=pool_header_json_filename, - table_mapping={"nt_symbols": symbol_table}, - class_types={"_POOL_HEADER": class_type}, - ) return table_name def run(self) -> renderers.TreeGrid: diff --git a/volatility3/framework/plugins/windows/psscan.py b/volatility3/framework/plugins/windows/psscan.py index 45f935ceb..99fa9640b 100644 --- a/volatility3/framework/plugins/windows/psscan.py +++ b/volatility3/framework/plugins/windows/psscan.py @@ -40,7 +40,7 @@ class PsScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): name="info", component=info.Info, version=(2, 0, 0) ), requirements.VersionRequirement( - name="poolscanner", component=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", component=poolscanner.PoolScanner, version=(3, 0, 0) ), requirements.ListRequirement( name="pid", diff --git a/volatility3/framework/plugins/windows/symlinkscan.py b/volatility3/framework/plugins/windows/symlinkscan.py index 459129843..358ea130e 100644 --- a/volatility3/framework/plugins/windows/symlinkscan.py +++ b/volatility3/framework/plugins/windows/symlinkscan.py @@ -28,7 +28,7 @@ class SymlinkScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterfa architectures=["Intel32", "Intel64"], ), requirements.VersionRequirement( - name="poolscanner", component=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", component=poolscanner.PoolScanner, version=(3, 0, 0) ), ] diff --git a/volatility3/framework/plugins/windows/windowstations.py b/volatility3/framework/plugins/windows/windowstations.py index 9d666e3dd..0ca92eb97 100644 --- a/volatility3/framework/plugins/windows/windowstations.py +++ b/volatility3/framework/plugins/windows/windowstations.py @@ -47,7 +47,7 @@ class WindowStations(interfaces.plugins.PluginInterface): architectures=["Intel32", "Intel64"], ), requirements.VersionRequirement( - name="poolscanner", component=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", component=poolscanner.PoolScanner, version=(3, 0, 0) ), requirements.VersionRequirement( name="modules", component=modules.Modules, version=(3, 0, 0) From b8c0b1eaa87d08b35aa42c1daa106668aa973a3c Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Mon, 10 Mar 2025 03:39:57 +0000 Subject: [PATCH 2/2] Add missing files --- volatility3/framework/plugins/windows/callbacks.py | 2 +- volatility3/framework/plugins/windows/driverscan.py | 2 +- volatility3/framework/plugins/windows/filescan.py | 2 +- volatility3/framework/plugins/windows/mutantscan.py | 2 +- volatility3/framework/plugins/windows/registry/hivescan.py | 2 +- volatility3/framework/plugins/windows/thrdscan.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/volatility3/framework/plugins/windows/callbacks.py b/volatility3/framework/plugins/windows/callbacks.py index 24f25c38d..bb326fd41 100644 --- a/volatility3/framework/plugins/windows/callbacks.py +++ b/volatility3/framework/plugins/windows/callbacks.py @@ -42,7 +42,7 @@ class Callbacks(interfaces.plugins.PluginInterface): name="ssdt", plugin=ssdt.SSDT, version=(2, 0, 0) ), requirements.PluginRequirement( - name="poolscanner", plugin=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", plugin=poolscanner.PoolScanner, version=(3, 0, 0) ), requirements.PluginRequirement( name="driverirp", plugin=driverirp.DriverIrp, version=(1, 0, 0) diff --git a/volatility3/framework/plugins/windows/driverscan.py b/volatility3/framework/plugins/windows/driverscan.py index 86db8d72b..57edfe0b6 100644 --- a/volatility3/framework/plugins/windows/driverscan.py +++ b/volatility3/framework/plugins/windows/driverscan.py @@ -25,7 +25,7 @@ class DriverScan(interfaces.plugins.PluginInterface): architectures=["Intel32", "Intel64"], ), requirements.PluginRequirement( - name="poolscanner", plugin=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", plugin=poolscanner.PoolScanner, version=(3, 0, 0) ), ] diff --git a/volatility3/framework/plugins/windows/filescan.py b/volatility3/framework/plugins/windows/filescan.py index abec2a92e..e0c823756 100644 --- a/volatility3/framework/plugins/windows/filescan.py +++ b/volatility3/framework/plugins/windows/filescan.py @@ -25,7 +25,7 @@ class FileScan(interfaces.plugins.PluginInterface): architectures=["Intel32", "Intel64"], ), requirements.PluginRequirement( - name="poolscanner", plugin=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", plugin=poolscanner.PoolScanner, version=(3, 0, 0) ), ] diff --git a/volatility3/framework/plugins/windows/mutantscan.py b/volatility3/framework/plugins/windows/mutantscan.py index ca6e26157..38685677a 100644 --- a/volatility3/framework/plugins/windows/mutantscan.py +++ b/volatility3/framework/plugins/windows/mutantscan.py @@ -25,7 +25,7 @@ class MutantScan(interfaces.plugins.PluginInterface): architectures=["Intel32", "Intel64"], ), requirements.PluginRequirement( - name="poolscanner", plugin=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", plugin=poolscanner.PoolScanner, version=(3, 0, 0) ), ] diff --git a/volatility3/framework/plugins/windows/registry/hivescan.py b/volatility3/framework/plugins/windows/registry/hivescan.py index a28ab19de..10843f8ab 100644 --- a/volatility3/framework/plugins/windows/registry/hivescan.py +++ b/volatility3/framework/plugins/windows/registry/hivescan.py @@ -26,7 +26,7 @@ class HiveScan(interfaces.plugins.PluginInterface): architectures=["Intel32", "Intel64"], ), requirements.PluginRequirement( - name="poolscanner", plugin=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", plugin=poolscanner.PoolScanner, version=(3, 0, 0) ), requirements.PluginRequirement( name="bigpools", plugin=bigpools.BigPools, version=(2, 0, 0) diff --git a/volatility3/framework/plugins/windows/thrdscan.py b/volatility3/framework/plugins/windows/thrdscan.py index b43593401..369db1fd8 100644 --- a/volatility3/framework/plugins/windows/thrdscan.py +++ b/volatility3/framework/plugins/windows/thrdscan.py @@ -34,7 +34,7 @@ class ThrdScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface) architectures=["Intel32", "Intel64"], ), requirements.PluginRequirement( - name="poolscanner", plugin=poolscanner.PoolScanner, version=(2, 0, 0) + name="poolscanner", plugin=poolscanner.PoolScanner, version=(3, 0, 0) ), ]