Add patch for driverscan for windows 7 and earlier

This patches an issue for some versions of windows that require the
bottom-up approach for finding the size of "object body" by
recognizing additional structures occupying the "object body"
position. The sizes of these additional structures are added to
the size of `_DRIVER_OBJECT` to more accurately compute the actual
size of "object body".
This commit is contained in:
Frank Gomulka
2021-07-28 08:38:53 -04:00
parent d1173b07ee
commit 6f4ff5f2df
2 changed files with 16 additions and 6 deletions
@@ -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,9 +18,8 @@ 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
@@ -34,6 +34,10 @@ class POOL_HEADER(objects.StructType):
An object as found from a POOL_HEADER
"""
# TODO: I wasn't quite sure what to do with these values, so I just set them here for now.
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 +154,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,
@@ -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,9 +294,8 @@ 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 = 'primary',
kernel_symbol_table = symbol_table)