Windows: Fixes bad callback validity check

This fixes a bug in the callbacks plugin which causes it to miss
`IoRegisterShutdownNotification` callbacks on x86b samples. The
`header.NameInfo.Name` field was being incorrectly treated as the device
type. This fixes the issue by updating the `is_valid` method on the
`_SHUTDOWN_PACKET` extension type to take a `type_map` parameter, and
updates the method to correctly validate the object type.
This commit is contained in:
David McDonald
2024-09-30 14:56:40 -05:00
parent 5a6958befa
commit 8ad592a490
2 changed files with 21 additions and 6 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
@@ -14,7 +15,7 @@ class _SHUTDOWN_PACKET(objects.StructType, pool.ExecutiveObject):
It exposes a function which sanity-checks structure members.
"""
def is_valid(self) -> bool:
def is_parseable(self, type_map: Dict[int, str]) -> bool:
"""
Perform some checks.
"""
@@ -24,6 +25,9 @@ class _SHUTDOWN_PACKET(objects.StructType, pool.ExecutiveObject):
and self.Entry.Blink.is_readable()
and self.DeviceObject.is_readable()
):
vollog.debug(
f"Callback obj 0x{self.vol.offset:x} invalid due to unreadable structure members"
)
return False
device = self.DeviceObject
@@ -41,10 +45,17 @@ class _SHUTDOWN_PACKET(objects.StructType, pool.ExecutiveObject):
try:
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 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