3
3
#
4
4
5
5
import logging
6
+ from typing import Iterator , List , Set , Tuple
6
7
7
- from typing import Iterator , List , Tuple
8
-
9
- from volatility3 .framework import constants , renderers , exceptions , interfaces
8
+ from volatility3 .framework import constants , exceptions , interfaces , renderers
10
9
from volatility3 .framework .configuration import requirements
11
10
from volatility3 .framework .renderers import format_hints
11
+ from volatility3 .framework .symbols .windows .extensions import DEVICE_OBJECT
12
12
from volatility3 .plugins .windows import driverscan
13
13
14
14
DEVICE_CODES = {
@@ -102,7 +102,7 @@ def _generator(self) -> Iterator[Tuple]:
102
102
):
103
103
try :
104
104
try :
105
- driver_name = driver .get_driver_name ()
105
+ driver_name = driver .DriverName . get_string ()
106
106
except (ValueError , exceptions .InvalidAddressException ):
107
107
vollog .log (
108
108
constants .LOGLEVEL_VVVV ,
@@ -124,59 +124,20 @@ def _generator(self) -> Iterator[Tuple]:
124
124
125
125
# Scan to get the device information of driver.
126
126
for device in driver .get_devices ():
127
- try :
128
- device_name = device .get_device_name ()
129
- except (ValueError , exceptions .InvalidAddressException ):
130
- vollog .log (
131
- constants .LOGLEVEL_VVVV ,
132
- f"Failed to get Device name : { device .vol .offset :x} " ,
133
- )
134
- device_name = renderers .UnparsableValue ()
135
-
136
- device_type = DEVICE_CODES .get (device .DeviceType , "UNKNOWN" )
137
-
138
- yield (
139
- 1 ,
140
- (
141
- format_hints .Hex (device .vol .offset ),
142
- "DEV" ,
143
- driver_name ,
144
- device_name ,
145
- renderers .NotApplicableValue (),
146
- device_type ,
147
- ),
148
- )
149
-
150
- # Scan to get the attached devices information of device.
151
- for level , attached_device in enumerate (
152
- device .get_attached_devices (), start = 2
153
- ):
154
- try :
155
- device_name = attached_device .get_device_name ()
156
- except (ValueError , exceptions .InvalidAddressException ):
157
- vollog .log (
158
- constants .LOGLEVEL_VVVV ,
159
- f"Failed to get Attached Device Name: { attached_device .vol .offset :x} " ,
160
- )
161
- device_name = renderers .UnparsableValue ()
162
-
163
- attached_device_driver_name = (
164
- attached_device .DriverObject .DriverName .get_string ()
165
- )
166
- attached_device_type = DEVICE_CODES .get (
167
- attached_device .DeviceType , "UNKNOWN"
168
- )
169
-
170
- yield (
171
- level ,
172
- (
173
- format_hints .Hex (attached_device .vol .offset ),
174
- "ATT" ,
175
- driver_name ,
176
- device_name ,
177
- attached_device_driver_name ,
178
- attached_device_type ,
179
- ),
127
+ for level , (
128
+ offset ,
129
+ drv_name ,
130
+ dev_name ,
131
+ att_drv_name ,
132
+ dev_typ ,
133
+ ) in self ._traverse_device_stack (device , driver_name , 1 ):
134
+ yield level , (
135
+ offset ,
136
+ "DEV" if level == 1 else "ATT" ,
137
+ drv_name ,
138
+ dev_name ,
139
+ att_drv_name ,
140
+ dev_typ ,
180
141
)
181
142
182
143
except exceptions .InvalidAddressException :
@@ -186,6 +147,48 @@ def _generator(self) -> Iterator[Tuple]:
186
147
)
187
148
continue
188
149
150
+ @staticmethod
151
+ def _traverse_device_stack (
152
+ device : DEVICE_OBJECT , driver_name : str , level : int , seen : Set [int ] = set ()
153
+ ) -> Iterator [Tuple ]:
154
+ while device and device .vol .offset not in seen :
155
+ seen .add (device .vol .offset )
156
+ try :
157
+ device_name = device .get_device_name ()
158
+ except (ValueError , exceptions .InvalidAddressException ):
159
+ vollog .log (
160
+ constants .LOGLEVEL_VVVV ,
161
+ f"Failed to get Device name : { device .vol .offset :x} " ,
162
+ )
163
+ device_name = renderers .UnparsableValue ()
164
+
165
+ device_type = DEVICE_CODES .get (device .DeviceType , "UNKNOWN" )
166
+
167
+ att_drv_name = device .DriverObject .DriverName .get_string ()
168
+
169
+ yield (
170
+ level ,
171
+ (
172
+ format_hints .Hex (device .vol .offset ),
173
+ driver_name ,
174
+ device_name ,
175
+ att_drv_name ,
176
+ device_type ,
177
+ ),
178
+ )
179
+ try :
180
+ attached = device .AttachedDevice .dereference ()
181
+ yield from DeviceTree ._traverse_device_stack (
182
+ attached , driver_name , level + 1 , seen
183
+ )
184
+ except exceptions .InvalidAddressException :
185
+ pass
186
+
187
+ try :
188
+ device = device .NextDevice .dereference ()
189
+ except exceptions .InvalidAddressException :
190
+ pass
191
+
189
192
def run (self ) -> renderers .TreeGrid :
190
193
return renderers .TreeGrid (
191
194
[
0 commit comments