Merge pull request #1276 from dgmcdona/dgmcdona/windows-callbacks-validity-check

Windows: Callbacks - fixes bad callback validity check
This commit is contained in:
ikelos
2024-10-01 00:42:29 +01:00
committed by GitHub
2 changed files with 42 additions and 10 deletions
@@ -248,8 +248,12 @@ class Callbacks(interfaces.plugins.PluginInterface):
context, layer_name, nt_symbol_table, constraints
):
try:
if hasattr(mem_object, "is_valid") and not mem_object.is_valid():
continue
if isinstance(mem_object, callbacks._SHUTDOWN_PACKET):
if not mem_object.is_parseable(type_map):
continue
elif hasattr(mem_object, "is_valid"):
if not mem_object.is_valid():
continue
yield cls._process_scanned_callback(mem_object, type_map)
except exceptions.InvalidAddressException:
@@ -1,4 +1,5 @@
import logging
from typing import Dict
from volatility3.framework import exceptions, objects
from volatility3.framework.symbols.windows.extensions import pool
@@ -24,12 +25,8 @@ class _SHUTDOWN_PACKET(objects.StructType, pool.ExecutiveObject):
and self.Entry.Blink.is_readable()
and self.DeviceObject.is_readable()
):
return False
device = self.DeviceObject
if not device or not (device.DriverObject.DriverStart % 0x1000 == 0):
vollog.debug(
f"callback obj 0x{self.vol.offset:x} invalid due to invalid device object"
f"Callback obj 0x{self.vol.offset:x} invalid due to unreadable structure members"
)
return False
@@ -39,12 +36,43 @@ class _SHUTDOWN_PACKET(objects.StructType, pool.ExecutiveObject):
)
return False
return True
def is_parseable(self, type_map: Dict[int, str]) -> bool:
"""
Determines whether or not this `_SHUTDOWN_PACKET` callback can be reliably parsed.
Requires a `type_map` that maps NT executive object type indices to string representations.
This type map can be acquired via the `handles.Handles.get_type_map` classmethod.
"""
if not self.is_valid():
return False
try:
device = self.DeviceObject
if not device or not (device.DriverObject.DriverStart % 0x1000 == 0):
vollog.debug(
f"callback obj 0x{self.vol.offset:x} invalid due to invalid device object"
)
return False
header = device.get_object_header()
valid = header.NameInfo.Name == "Device"
return valid
object_type = header.get_object_type(type_map)
is_valid = object_type == "Device"
if not is_valid:
vollog.debug(
f"Callback obj 0x{self.vol.offset:x} invalid due to invalid device type: wanted 'Device', found '{object_type}'"
)
return is_valid
except exceptions.InvalidAddressException:
vollog.debug(
f"callback obj 0x{self.vol.offset:x} invalid due to invalid address access"
)
return False
except ValueError:
vollog.debug(f"Could not get NameInfo for object at 0x{self.vol.offset:x}")
vollog.debug(
f"Could not get object type for object at 0x{self.vol.offset:x}"
)
return False