Skip to content

Commit 0ffb550

Browse files
committed
Do not yield junk driver objects, conform to current API return values
1 parent 8df8f77 commit 0ffb550

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

volatility3/framework/plugins/windows/driverscan.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
33
#
44

5-
from typing import Iterable
5+
from typing import Iterable, Optional, Tuple
66

77
from volatility3.framework import renderers, interfaces, exceptions
88
from volatility3.framework.configuration import requirements
@@ -51,6 +51,10 @@ def scan_drivers(
5151
symbol_table, [b"Dri\xf6", b"Driv"]
5252
)
5353

54+
layer = context.layers[layer_name]
55+
module = context.module(symbol_table, layer_name, 0)
56+
driver_start_offset = module.get_type("_DRIVER_OBJECT").relative_child_offset("DriverStart")
57+
5458
for result in poolscanner.PoolScanner.generate_pool_scan(
5559
context, layer_name, symbol_table, constraints
5660
):
@@ -62,15 +66,16 @@ def scan_drivers(
6266
# `DriverStart` is the first member from the beginning of the structure
6367
# of interest to plugins, so if it is not accessible then this instance
6468
# is not useful or usable during analysis
65-
try:
66-
mem_object.DriverStart
67-
except exceptions.InvalidAddressException:
68-
continue
69+
# 8 covers this value 32 and 64 bit systems
70+
if layer.is_valid(mem_object.vol.offset + driver_start_offset, 8):
6971

70-
yield mem_object
72+
# Many/most rootkits zero out their DriverStart member for anti-forensics
73+
# so we accept a driver start that is either 0 or is mapped in kernel memory (the current layer)
74+
if mem_object.DriverStart == 0 or layer.is_valid(mem_object.DriverStart, 8):
75+
yield mem_object
7176

7277
@classmethod
73-
def get_names_for_driver(cls, driver):
78+
def get_names_for_driver(cls, driver) -> Tuple[Optional[str], Optional[str], Optional[str]]:
7479
"""
7580
Convenience method for getting the commonly used
7681
names associated with a driver
@@ -84,17 +89,17 @@ def get_names_for_driver(cls, driver):
8489
try:
8590
driver_name = driver.get_driver_name()
8691
except (ValueError, exceptions.InvalidAddressException):
87-
driver_name = renderers.NotApplicableValue()
92+
driver_name = None
8893

8994
try:
9095
service_key = driver.DriverExtension.ServiceKeyName.String
9196
except exceptions.InvalidAddressException:
92-
service_key = renderers.NotApplicableValue()
97+
service_key = None
9398

9499
try:
95100
name = driver.DriverName.String
96101
except exceptions.InvalidAddressException:
97-
name = renderers.NotApplicableValue()
102+
name = None
98103

99104
return driver_name, service_key, name
100105

@@ -106,15 +111,19 @@ def _generator(self):
106111
):
107112
driver_name, service_key, name = self.get_names_for_driver(driver)
108113

114+
# Prior to #1481, this plugin reported dozens to hundreds of junk drivers per sample
115+
if driver.DriverStart == 0 and not driver_name and not service_key and not name:
116+
continue
117+
109118
yield (
110119
0,
111120
(
112121
format_hints.Hex(driver.vol.offset),
113122
format_hints.Hex(driver.DriverStart),
114123
format_hints.Hex(driver.DriverSize),
115-
service_key,
116-
driver_name,
117-
name,
124+
service_key or renderers.NotAvailableValue(),
125+
driver_name or renderers.NotAvailableValue(),
126+
name or renderers.NotAvailableValue(),
118127
),
119128
)
120129

0 commit comments

Comments
 (0)