From 9919c1e6142a141330e93bb7fa751ed4709a4151 Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Sat, 8 Mar 2025 22:49:16 +0000 Subject: [PATCH] Fix handles API and callers. Bump version number and requirements --- .../framework/plugins/windows/callbacks.py | 4 +- .../framework/plugins/windows/dumpfiles.py | 8 ++- .../framework/plugins/windows/handles.py | 50 ++++++------------- .../framework/plugins/windows/poolscanner.py | 10 ++-- .../framework/plugins/windows/psxview.py | 10 ++-- 5 files changed, 27 insertions(+), 55 deletions(-) diff --git a/volatility3/framework/plugins/windows/callbacks.py b/volatility3/framework/plugins/windows/callbacks.py index c832df66a..24f25c38d 100644 --- a/volatility3/framework/plugins/windows/callbacks.py +++ b/volatility3/framework/plugins/windows/callbacks.py @@ -48,7 +48,7 @@ class Callbacks(interfaces.plugins.PluginInterface): name="driverirp", plugin=driverirp.DriverIrp, version=(1, 0, 0) ), requirements.PluginRequirement( - name="handles", plugin=handles.Handles, version=(2, 0, 0) + name="handles", plugin=handles.Handles, version=(3, 0, 0) ), ] @@ -237,7 +237,7 @@ class Callbacks(interfaces.plugins.PluginInterface): ) type_map = handles.Handles.get_type_map( - context, kernel.layer_name, kernel.symbol_table_name + context=context, kernel_module_name=kernel_module_name ) constraints = cls.create_callback_scan_constraints( diff --git a/volatility3/framework/plugins/windows/dumpfiles.py b/volatility3/framework/plugins/windows/dumpfiles.py index e89b99275..e0adad2b1 100755 --- a/volatility3/framework/plugins/windows/dumpfiles.py +++ b/volatility3/framework/plugins/windows/dumpfiles.py @@ -71,7 +71,7 @@ class DumpFiles(interfaces.plugins.PluginInterface): name="pslist", component=pslist.PsList, version=(3, 0, 0) ), requirements.VersionRequirement( - name="handles", component=handles.Handles, version=(2, 0, 0) + name="handles", component=handles.Handles, version=(3, 0, 0) ), ] @@ -231,13 +231,11 @@ class DumpFiles(interfaces.plugins.PluginInterface): ) type_map = handles_plugin.get_type_map( context=self.context, - layer_name=kernel.layer_name, - symbol_table=kernel.symbol_table_name, + kernel_module_name=self.config["kernel"], ) cookie = handles_plugin.find_cookie( context=self.context, - layer_name=kernel.layer_name, - symbol_table=kernel.symbol_table_name, + kernel_module_name=self.config["kernel"], ) dumped_files = set() diff --git a/volatility3/framework/plugins/windows/handles.py b/volatility3/framework/plugins/windows/handles.py index e39c23a30..9627b5caa 100644 --- a/volatility3/framework/plugins/windows/handles.py +++ b/volatility3/framework/plugins/windows/handles.py @@ -18,7 +18,7 @@ class Handles(interfaces.plugins.PluginInterface): """Lists process open handles.""" _required_framework_version = (2, 0, 0) - _version = (2, 0, 1) + _version = (3, 0, 0) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -121,8 +121,7 @@ class Handles(interfaces.plugins.PluginInterface): def get_type_map( cls, context: interfaces.context.ContextInterface, - layer_name: str, - symbol_table: str, + kernel_module_name: str, ) -> Dict[int, str]: """List the executive object types (_OBJECT_TYPE) using the ObTypeIndexTable or ObpObjectTypes symbol (differs per OS). This method @@ -144,21 +143,16 @@ class Handles(interfaces.plugins.PluginInterface): type_map: Dict[int, str] = {} - kvo = context.layers[layer_name].config.get("kernel_virtual_offset", None) - if not kvo: - raise ValueError( - "Intel layer does not have an associated kernel virtual offset, failing" - ) - ntkrnlmp = context.module(symbol_table, layer_name=layer_name, offset=kvo) + ntkrnlmp = context.modules[kernel_module_name] try: table_addr = ntkrnlmp.get_symbol("ObTypeIndexTable").address except exceptions.SymbolError: table_addr = ntkrnlmp.get_symbol("ObpObjectTypes").address - trans_layer = context.layers[layer_name] + trans_layer = context.layers[ntkrnlmp.layer_name] - if not trans_layer.is_valid(kvo + table_addr): + if not trans_layer.is_valid(ntkrnlmp.offset + table_addr): return type_map ptrs = ntkrnlmp.object( @@ -176,7 +170,7 @@ class Handles(interfaces.plugins.PluginInterface): try: objt = ptr.dereference().cast( - symbol_table + constants.BANG + "_OBJECT_TYPE" + ntkrnlmp.symbol_table_name + constants.BANG + "_OBJECT_TYPE" ) type_name = objt.Name.String except exceptions.InvalidAddressException: @@ -194,27 +188,21 @@ class Handles(interfaces.plugins.PluginInterface): def find_cookie( cls, context: interfaces.context.ContextInterface, - layer_name: str, - symbol_table: str, + kernel_module_name: str, ) -> Optional[interfaces.objects.ObjectInterface]: """Find the ObHeaderCookie value (if it exists)""" + kernel = context.modules[kernel_module_name] + try: - offset = context.symbol_space.get_symbol( - symbol_table + constants.BANG + "ObHeaderCookie" - ).address + symbol_offset = kernel.get_symbol("ObHeaderCookie").address except exceptions.SymbolError: + vollog.debug('Unable to get symbol information for "ObHeaderCookie"') return None - kvo = context.layers[layer_name].config.get("kernel_virtual_offset", None) - if not kvo: - raise ValueError( - "Intel layer does not have an associated kernel virtual offset, failing" - ) - return context.object( - symbol_table + constants.BANG + "unsigned int", - layer_name, - offset=kvo + offset, + return kernel.object( + "unsigned int", + offset=symbol_offset, ) def _make_handle_array(self, offset, level, depth=0): @@ -298,18 +286,12 @@ class Handles(interfaces.plugins.PluginInterface): yield from self._make_handle_array(TableCode, table_levels) def _generator(self, procs): - kernel = self.context.modules[self.config["kernel"]] - type_map = self.get_type_map( - context=self.context, - layer_name=kernel.layer_name, - symbol_table=kernel.symbol_table_name, + context=self.context, kernel_module_name=self.config["kernel"] ) cookie = self.find_cookie( - context=self.context, - layer_name=kernel.layer_name, - symbol_table=kernel.symbol_table_name, + context=self.context, kernel_module_name=self.config["kernel"] ) for proc in procs: diff --git a/volatility3/framework/plugins/windows/poolscanner.py b/volatility3/framework/plugins/windows/poolscanner.py index c78c47c43..5e75d9bbb 100644 --- a/volatility3/framework/plugins/windows/poolscanner.py +++ b/volatility3/framework/plugins/windows/poolscanner.py @@ -140,7 +140,7 @@ class PoolScanner(plugins.PluginInterface): architectures=["Intel32", "Intel64"], ), requirements.PluginRequirement( - name="handles", plugin=handles.Handles, version=(2, 0, 0) + name="handles", plugin=handles.Handles, version=(3, 0, 0) ), ] @@ -394,15 +394,11 @@ class PoolScanner(plugins.PluginInterface): # get the object type map type_map = handles.Handles.get_type_map( - context=context, - layer_name=kernel.layer_name, - symbol_table=kernel.symbol_table_name, + context=context, kernel_module_name=kernel_module_name ) cookie = handles.Handles.find_cookie( - context=context, - layer_name=kernel.layer_name, - symbol_table=kernel.symbol_table_name, + context=context, kernel_module_name=kernel_module_name ) is_windows_10 = versions.is_windows_10(context, kernel.symbol_table_name) diff --git a/volatility3/framework/plugins/windows/psxview.py b/volatility3/framework/plugins/windows/psxview.py index 3377163f7..7329588cc 100644 --- a/volatility3/framework/plugins/windows/psxview.py +++ b/volatility3/framework/plugins/windows/psxview.py @@ -58,7 +58,7 @@ We recommend using -r pretty if you are looking at this plugin's output in a ter name="thrdscan", component=thrdscan.ThrdScan, version=(1, 0, 0) ), requirements.VersionRequirement( - name="handles", component=handles.Handles, version=(2, 0, 0) + name="handles", component=handles.Handles, version=(3, 0, 0) ), requirements.BooleanRequirement( name="physical-offsets", @@ -144,20 +144,16 @@ We recommend using -r pretty if you are looking at this plugin's output in a ter ) -> Dict[int, extensions.EPROCESS]: ret: List[extensions.EPROCESS] = [] - kernel = self.context.modules[self.config["kernel"]] - handles_plugin = handles.Handles( context=self.context, config_path=self.config_path ) type_map = handles_plugin.get_type_map( - self.context, kernel.layer_name, kernel.symbol_table_name + context=self.context, kernel_module_name=self.config["kernel"] ) cookie = handles_plugin.find_cookie( - context=self.context, - layer_name=kernel.layer_name, - symbol_table=kernel.symbol_table_name, + context=self.context, kernel_module_name=self.config["kernel"] ) for p in tasks: