diff --git a/volatility3/framework/symbols/windows/extensions/pool.py b/volatility3/framework/symbols/windows/extensions/pool.py index d470797b5..5353fc30b 100644 --- a/volatility3/framework/symbols/windows/extensions/pool.py +++ b/volatility3/framework/symbols/windows/extensions/pool.py @@ -5,6 +5,7 @@ from typing import Optional, Tuple, List, Dict, Union from volatility3.framework import objects, interfaces, constants, symbols, exceptions, renderers from volatility3.framework.renderers import conversion +from volatility3.plugins.windows.poolscanner import PoolConstraint vollog = logging.getLogger(__name__) @@ -17,23 +18,25 @@ class POOL_HEADER(objects.StructType): """ def get_object(self, - type_name: str, + constraint: PoolConstraint, use_top_down: bool, - executive: bool = False, kernel_symbol_table: Optional[str] = None, native_layer_name: Optional[str] = None) -> Optional[interfaces.objects.ObjectInterface]: """Carve an object or data structure from a kernel pool allocation Args: - type_name: the data structure type name - native_layer_name: the name of the layer where the data originally lived - object_type: the object type (executive kernel objects only) + constraint: a PoolConstraint object used to get the pool allocation header object + use_top_down: for delineating how a windows version finds the size of the object body kernel_symbol_table: in case objects of a different symbol table are scanned for + native_layer_name: the name of the layer where the data originally lived Returns: An object as found from a POOL_HEADER """ + type_name = constraint.type_name + executive = constraint.object_type is not None + symbol_table_name = self.vol.type_name.split(constants.BANG)[0] if constants.BANG in type_name: symbol_table_name, type_name = type_name.split(constants.BANG)[0:2] @@ -150,6 +153,10 @@ class POOL_HEADER(objects.StructType): # use the bottom up approach for windows 7 and earlier else: type_size = self._context.symbol_space.get_type(symbol_table_name + constants.BANG + type_name).size + if constraint.additional_structures: + for additional_structure in constraint.additional_structures: + type_size += self._context.symbol_space.get_type(symbol_table_name + constants.BANG + additional_structure).size + rounded_size = conversion.round(type_size, alignment, up = True) mem_object = self._context.object(symbol_table_name + constants.BANG + type_name, diff --git a/volatility3/framework/plugins/windows/poolscanner.py b/volatility3/plugins/windows/poolscanner.py similarity index 97% rename from volatility3/framework/plugins/windows/poolscanner.py rename to volatility3/plugins/windows/poolscanner.py index e1abb1b7f..951edac66 100644 --- a/volatility3/framework/plugins/windows/poolscanner.py +++ b/volatility3/plugins/windows/poolscanner.py @@ -39,7 +39,8 @@ class PoolConstraint: size: Optional[Tuple[Optional[int], Optional[int]]] = None, index: Optional[Tuple[Optional[int], Optional[int]]] = None, alignment: Optional[int] = 1, - skip_type_test: bool = False) -> None: + skip_type_test: bool = False, + additional_structures: Optional[List[str]] = None) -> None: self.tag = tag self.type_name = type_name self.object_type = object_type @@ -48,6 +49,7 @@ class PoolConstraint: self.index = index self.alignment = alignment self.skip_type_test = skip_type_test + self.additional_structures = additional_structures class PoolHeaderScanner(interfaces.layers.ScannerInterface): @@ -212,7 +214,8 @@ class PoolScanner(plugins.PluginInterface): type_name = symbol_table + constants.BANG + "_DRIVER_OBJECT", object_type = "Driver", size = (248, None), - page_type = PoolType.PAGED | PoolType.NONPAGED | PoolType.FREE), + page_type = PoolType.PAGED | PoolType.NONPAGED | PoolType.FREE, + additional_structures = ["_DRIVER_EXTENSION"]), # drivers on windows starting with windows 8 PoolConstraint(b'Driv', type_name = symbol_table + constants.BANG + "_DRIVER_OBJECT", @@ -291,10 +294,9 @@ class PoolScanner(plugins.PluginInterface): for constraint, header in cls.pool_scan(context, scan_layer, symbol_table, constraints, alignment = alignment): - mem_object = header.get_object(type_name = constraint.type_name, + mem_object = header.get_object(constraint = constraint, use_top_down = is_windows_8_or_later, - executive = constraint.object_type is not None, - native_layer_name = layer_name, + native_layer_name = 'primary', kernel_symbol_table = symbol_table) if mem_object is None: