|
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