33#
44
55import logging
6+ from typing import Iterator , List , Set , Tuple
67
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
109from volatility3 .framework .configuration import requirements
1110from volatility3 .framework .renderers import format_hints
11+ from volatility3 .framework .symbols .windows .extensions import DEVICE_OBJECT
1212from volatility3 .plugins .windows import driverscan
1313
1414DEVICE_CODES = {
@@ -102,7 +102,7 @@ def _generator(self) -> Iterator[Tuple]:
102102 ):
103103 try :
104104 try :
105- driver_name = driver .get_driver_name ()
105+ driver_name = driver .DriverName . get_string ()
106106 except (ValueError , exceptions .InvalidAddressException ):
107107 vollog .log (
108108 constants .LOGLEVEL_VVVV ,
@@ -124,59 +124,20 @@ def _generator(self) -> Iterator[Tuple]:
124124
125125 # Scan to get the device information of driver.
126126 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 ,
180141 )
181142
182143 except exceptions .InvalidAddressException :
@@ -186,6 +147,48 @@ def _generator(self) -> Iterator[Tuple]:
186147 )
187148 continue
188149
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+
189192 def run (self ) -> renderers .TreeGrid :
190193 return renderers .TreeGrid (
191194 [
0 commit comments