Fix handles API and callers. Bump version number and requirements

This commit is contained in:
Andrew Case
2025-03-08 22:49:16 +00:00
parent 67b8f2ce47
commit 9919c1e614
5 changed files with 27 additions and 55 deletions
@@ -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(
@@ -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()
@@ -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:
@@ -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)
@@ -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: