Skip to content

Commit

Permalink
Merge pull request volatilityfoundation#1276 from dgmcdona/dgmcdona/w…
Browse files Browse the repository at this point in the history
…indows-callbacks-validity-check

Windows: Callbacks - fixes bad callback validity check
  • Loading branch information
ikelos authored Sep 30, 2024
2 parents c37d9ee + db55f23 commit 5d2a5f9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
8 changes: 6 additions & 2 deletions volatility3/framework/plugins/windows/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,12 @@ def scan(
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:
Expand Down
40 changes: 34 additions & 6 deletions volatility3/framework/symbols/windows/extensions/callbacks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from typing import Dict

from volatility3.framework import exceptions, objects
from volatility3.framework.symbols.windows.extensions import pool
Expand All @@ -24,27 +25,54 @@ def is_valid(self) -> bool:
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

except exceptions.InvalidAddressException:
vollog.debug(
f"callback obj 0x{self.vol.offset:x} invalid due to invalid address access"
)
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()
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

try:
header = device.get_object_header()
valid = header.NameInfo.Name == "Device"
return 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


Expand Down

0 comments on commit 5d2a5f9

Please sign in to comment.