|
3 | 3 | # |
4 | 4 |
|
5 | 5 | import logging |
6 | | -from typing import Iterator, List, Set, Tuple |
| 6 | +from typing import Iterator, List, Set, Tuple, Union |
7 | 7 |
|
8 | 8 | from volatility3.framework import constants, exceptions, interfaces, renderers |
9 | 9 | from volatility3.framework.configuration import requirements |
10 | 10 | from volatility3.framework.renderers import format_hints |
11 | | -from volatility3.framework.symbols.windows.extensions import DEVICE_OBJECT |
| 11 | +from volatility3.framework.symbols.windows import extensions |
12 | 12 | from volatility3.plugins.windows import driverscan |
13 | 13 |
|
14 | | -DEVICE_CODES = { |
15 | | - 0x00000027: "FILE_DEVICE_8042_PORT", |
16 | | - 0x00000032: "FILE_DEVICE_ACPI", |
17 | | - 0x00000029: "FILE_DEVICE_BATTERY", |
18 | | - 0x00000001: "FILE_DEVICE_BEEP", |
19 | | - 0x0000002A: "FILE_DEVICE_BUS_EXTENDER", |
20 | | - 0x00000002: "FILE_DEVICE_CD_ROM", |
21 | | - 0x00000003: "FILE_DEVICE_CD_ROM_FILE_SYSTEM", |
22 | | - 0x00000030: "FILE_DEVICE_CHANGER", |
23 | | - 0x00000004: "FILE_DEVICE_CONTROLLER", |
24 | | - 0x00000005: "FILE_DEVICE_DATALINK", |
25 | | - 0x00000006: "FILE_DEVICE_DFS", |
26 | | - 0x00000035: "FILE_DEVICE_DFS_FILE_SYSTEM", |
27 | | - 0x00000036: "FILE_DEVICE_DFS_VOLUME", |
28 | | - 0x00000007: "FILE_DEVICE_DISK", |
29 | | - 0x00000008: "FILE_DEVICE_DISK_FILE_SYSTEM", |
30 | | - 0x00000033: "FILE_DEVICE_DVD", |
31 | | - 0x00000009: "FILE_DEVICE_FILE_SYSTEM", |
32 | | - 0x0000003A: "FILE_DEVICE_FIPS", |
33 | | - 0x00000034: "FILE_DEVICE_FULLSCREEN_VIDEO", |
34 | | - 0x0000000A: "FILE_DEVICE_INPORT_PORT", |
35 | | - 0x0000000B: "FILE_DEVICE_KEYBOARD", |
36 | | - 0x0000002F: "FILE_DEVICE_KS", |
37 | | - 0x00000039: "FILE_DEVICE_KSEC", |
38 | | - 0x0000000C: "FILE_DEVICE_MAILSLOT", |
39 | | - 0x0000002D: "FILE_DEVICE_MASS_STORAGE", |
40 | | - 0x0000000D: "FILE_DEVICE_MIDI_IN", |
41 | | - 0x0000000E: "FILE_DEVICE_MIDI_OUT", |
42 | | - 0x0000002B: "FILE_DEVICE_MODEM", |
43 | | - 0x0000000F: "FILE_DEVICE_MOUSE", |
44 | | - 0x00000010: "FILE_DEVICE_MULTI_UNC_PROVIDER", |
45 | | - 0x00000011: "FILE_DEVICE_NAMED_PIPE", |
46 | | - 0x00000012: "FILE_DEVICE_NETWORK", |
47 | | - 0x00000013: "FILE_DEVICE_NETWORK_BROWSER", |
48 | | - 0x00000014: "FILE_DEVICE_NETWORK_FILE_SYSTEM", |
49 | | - 0x00000028: "FILE_DEVICE_NETWORK_REDIRECTOR", |
50 | | - 0x00000015: "FILE_DEVICE_NULL", |
51 | | - 0x00000016: "FILE_DEVICE_PARALLEL_PORT", |
52 | | - 0x00000017: "FILE_DEVICE_PHYSICAL_NETCARD", |
53 | | - 0x00000018: "FILE_DEVICE_PRINTER", |
54 | | - 0x00000019: "FILE_DEVICE_SCANNER", |
55 | | - 0x0000001C: "FILE_DEVICE_SCREEN", |
56 | | - 0x00000037: "FILE_DEVICE_SERENUM", |
57 | | - 0x0000001A: "FILE_DEVICE_SERIAL_MOUSE_PORT", |
58 | | - 0x0000001B: "FILE_DEVICE_SERIAL_PORT", |
59 | | - 0x00000031: "FILE_DEVICE_SMARTCARD", |
60 | | - 0x0000002E: "FILE_DEVICE_SMB", |
61 | | - 0x0000001D: "FILE_DEVICE_SOUND", |
62 | | - 0x0000001E: "FILE_DEVICE_STREAMS", |
63 | | - 0x0000001F: "FILE_DEVICE_TAPE", |
64 | | - 0x00000020: "FILE_DEVICE_TAPE_FILE_SYSTEM", |
65 | | - 0x00000038: "FILE_DEVICE_TERMSRV", |
66 | | - 0x00000021: "FILE_DEVICE_TRANSPORT", |
67 | | - 0x00000022: "FILE_DEVICE_UNKNOWN", |
68 | | - 0x0000002C: "FILE_DEVICE_VDM", |
69 | | - 0x00000023: "FILE_DEVICE_VIDEO", |
70 | | - 0x00000024: "FILE_DEVICE_VIRTUAL_DISK", |
71 | | - 0x00000025: "FILE_DEVICE_WAVE_IN", |
72 | | - 0x00000026: "FILE_DEVICE_WAVE_OUT", |
73 | | -} |
74 | | - |
75 | 14 | vollog = logging.getLogger(__name__) |
76 | 15 |
|
77 | 16 |
|
@@ -101,97 +40,76 @@ def _generator(self) -> Iterator[Tuple]: |
101 | 40 | self.config["kernel"], |
102 | 41 | ): |
103 | 42 | try: |
104 | | - try: |
105 | | - driver_name = driver.DriverName.get_string() |
106 | | - except (ValueError, exceptions.InvalidAddressException): |
107 | | - vollog.log( |
108 | | - constants.LOGLEVEL_VVVV, |
109 | | - f"Failed to get Driver name : {driver.vol.offset:x}", |
110 | | - ) |
111 | | - driver_name = renderers.UnparsableValue() |
112 | | - |
113 | | - yield ( |
114 | | - 0, |
115 | | - ( |
116 | | - format_hints.Hex(driver.vol.offset), |
117 | | - "DRV", |
118 | | - driver_name, |
119 | | - renderers.NotApplicableValue(), |
120 | | - renderers.NotApplicableValue(), |
121 | | - renderers.NotApplicableValue(), |
122 | | - ), |
123 | | - ) |
124 | | - |
125 | | - # Scan to get the device information of driver. |
126 | | - for device in driver.get_devices(): |
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, |
141 | | - ) |
142 | | - |
143 | | - except exceptions.InvalidAddressException: |
| 43 | + driver_name = driver.DriverName.get_string() |
| 44 | + except (ValueError, exceptions.InvalidAddressException): |
144 | 45 | vollog.log( |
145 | 46 | constants.LOGLEVEL_VVVV, |
146 | | - f"Invalid address identified in drivers and devices: {driver.vol.offset:x}", |
| 47 | + f"Failed to get Driver name : {driver.vol.offset:x}", |
147 | 48 | ) |
148 | | - continue |
| 49 | + driver_name = renderers.UnparsableValue() |
| 50 | + |
| 51 | + yield ( |
| 52 | + 0, |
| 53 | + ( |
| 54 | + format_hints.Hex(driver.vol.offset), |
| 55 | + "DRV", |
| 56 | + driver_name, |
| 57 | + renderers.NotApplicableValue(), |
| 58 | + renderers.NotApplicableValue(), |
| 59 | + renderers.NotApplicableValue(), |
| 60 | + ), |
| 61 | + ) |
| 62 | + |
| 63 | + # Scan to get the device information of driver. |
| 64 | + for device in driver.get_devices(): |
| 65 | + for level, device_entry in self._traverse_device_stack(device, 1): |
| 66 | + try: |
| 67 | + device_name = device.get_device_name() |
| 68 | + except exceptions.InvalidAddressException: |
| 69 | + device_name = renderers.UnparsableValue() |
| 70 | + |
| 71 | + try: |
| 72 | + attached_driver_name = device.get_attached_driver_name() |
| 73 | + except exceptions.InvalidAddressException: |
| 74 | + attached_driver_name = renderers.UnparsableValue() |
| 75 | + |
| 76 | + try: |
| 77 | + device_type = device.get_device_type() |
| 78 | + except exceptions.InvalidAddressException: |
| 79 | + device_type = renderers.UnparsableValue() |
| 80 | + |
| 81 | + yield level, ( |
| 82 | + format_hints.Hex(device_entry.vol.offset), |
| 83 | + "DEV" if level == 1 else "ATT", |
| 84 | + driver_name, |
| 85 | + device_name, |
| 86 | + attached_driver_name, |
| 87 | + device_type, |
| 88 | + ) |
149 | 89 |
|
150 | | - @staticmethod |
| 90 | + @classmethod |
151 | 91 | def _traverse_device_stack( |
152 | | - device: DEVICE_OBJECT, driver_name: str, level: int, seen: Set[int] = set() |
153 | | - ) -> Iterator[Tuple]: |
| 92 | + cls, device: extensions.DEVICE_OBJECT, level: int, seen: Set[int] = set() |
| 93 | + ) -> Iterator[Tuple[int, extensions.DEVICE_OBJECT]]: |
154 | 94 | while device and device.vol.offset not in seen: |
155 | 95 | 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 | 96 |
|
| 97 | + # Yield the first device and its level |
169 | 98 | yield ( |
170 | 99 | level, |
171 | | - ( |
172 | | - format_hints.Hex(device.vol.offset), |
173 | | - driver_name, |
174 | | - device_name, |
175 | | - att_drv_name, |
176 | | - device_type, |
177 | | - ), |
| 100 | + device, |
178 | 101 | ) |
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 | | - vollog.debug( |
186 | | - f"Failed to dereference attached device for device at {device.vol.offset:#x}, " |
187 | | - "devnode may not have drivers associated with it" |
188 | | - ) |
| 102 | + |
| 103 | + for attached in device.get_attached_devices(): |
| 104 | + # Go depth-first through all of this device's child devices |
| 105 | + yield from cls._traverse_device_stack(attached, level + 1, seen) |
189 | 106 |
|
190 | 107 | try: |
| 108 | + # Then move sideways to the next device in the current linked list |
191 | 109 | device = device.NextDevice.dereference() |
192 | 110 | except exceptions.InvalidAddressException: |
193 | 111 | vollog.debug( |
194 | | - f"Failed to dereference next driver in linked list at {int(device.NextDevice)}, " |
| 112 | + f"Failed to dereference next driver in linked list, " |
195 | 113 | "may have reached end of list" |
196 | 114 | ) |
197 | 115 |
|
|
0 commit comments