Skip to content

Commit 8ad592a

Browse files
committed
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.
1 parent 5a6958b commit 8ad592a

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

volatility3/framework/plugins/windows/callbacks.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,12 @@ def scan(
248248
context, layer_name, nt_symbol_table, constraints
249249
):
250250
try:
251-
if hasattr(mem_object, "is_valid") and not mem_object.is_valid():
252-
continue
251+
if isinstance(mem_object, callbacks._SHUTDOWN_PACKET):
252+
if not mem_object.is_parseable(type_map):
253+
continue
254+
elif hasattr(mem_object, "is_valid"):
255+
if not mem_object.is_valid():
256+
continue
253257

254258
yield cls._process_scanned_callback(mem_object, type_map)
255259
except exceptions.InvalidAddressException:

volatility3/framework/symbols/windows/extensions/callbacks.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from typing import Dict
23

34
from volatility3.framework import exceptions, objects
45
from volatility3.framework.symbols.windows.extensions import pool
@@ -14,7 +15,7 @@ class _SHUTDOWN_PACKET(objects.StructType, pool.ExecutiveObject):
1415
It exposes a function which sanity-checks structure members.
1516
"""
1617

17-
def is_valid(self) -> bool:
18+
def is_parseable(self, type_map: Dict[int, str]) -> bool:
1819
"""
1920
Perform some checks.
2021
"""
@@ -24,6 +25,9 @@ def is_valid(self) -> bool:
2425
and self.Entry.Blink.is_readable()
2526
and self.DeviceObject.is_readable()
2627
):
28+
vollog.debug(
29+
f"Callback obj 0x{self.vol.offset:x} invalid due to unreadable structure members"
30+
)
2731
return False
2832

2933
device = self.DeviceObject
@@ -41,10 +45,17 @@ def is_valid(self) -> bool:
4145

4246
try:
4347
header = device.get_object_header()
44-
valid = header.NameInfo.Name == "Device"
45-
return valid
48+
object_type = header.get_object_type(type_map)
49+
is_valid = object_type == "Device"
50+
if not is_valid:
51+
vollog.debug(
52+
f"Callback obj 0x{self.vol.offset:x} invalid due to invalid device type: wanted 'Device', found '{object_type}'"
53+
)
54+
return is_valid
4655
except ValueError:
47-
vollog.debug(f"Could not get NameInfo for object at 0x{self.vol.offset:x}")
56+
vollog.debug(
57+
f"Could not get object type for object at 0x{self.vol.offset:x}"
58+
)
4859
return False
4960

5061

0 commit comments

Comments
 (0)