|
10 | 10 | Dict, |
11 | 11 | ) |
12 | 12 |
|
| 13 | +import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules |
13 | 14 | from volatility3 import framework |
14 | 15 | from volatility3.framework import ( |
15 | 16 | interfaces, |
16 | 17 | exceptions, |
17 | 18 | symbols, |
18 | 19 | ) |
| 20 | +from volatility3.framework.configuration import requirements |
19 | 21 | from volatility3.framework.constants import linux as linux_constants |
20 | 22 | from volatility3.framework.symbols.linux import extensions |
21 | 23 |
|
|
38 | 40 | class ModuleExtract(interfaces.configuration.VersionableInterface): |
39 | 41 | """Extracts Linux kernel module structures into an analyzable ELF file""" |
40 | 42 |
|
41 | | - _version = (1, 0, 1) |
| 43 | + _version = (1, 0, 2) |
42 | 44 | _required_framework_version = (2, 25, 0) |
43 | 45 |
|
44 | 46 | framework.require_interface_version(*_required_framework_version) |
45 | 47 |
|
| 48 | + @classmethod |
| 49 | + def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: |
| 50 | + return [ |
| 51 | + requirements.VersionRequirement( |
| 52 | + name="linux_utilities_modules", |
| 53 | + component=linux_utilities_modules.Modules, |
| 54 | + version=(3, 0, 2), |
| 55 | + ), |
| 56 | + ] |
| 57 | + |
46 | 58 | @classmethod |
47 | 59 | def _find_section( |
48 | 60 | cls, section_lookups: List[Tuple[str, int, int, int]], sym_address: int |
@@ -237,17 +249,32 @@ def _parse_sections( |
237 | 249 | The data of .strtab is read directly off the module structure and not its section |
238 | 250 | as the section from the original module has no meaning after loading as the kernel does not reference it. |
239 | 251 | """ |
| 252 | + kernel = context.modules[vmlinux_name] |
| 253 | + kernel_layer = context.layers[kernel.layer_name] |
| 254 | + modules_addr_min, modules_addr_max = ( |
| 255 | + linux_utilities_modules.Modules.get_modules_memory_boundaries( |
| 256 | + context, vmlinux_name |
| 257 | + ) |
| 258 | + ) |
| 259 | + modules_addr_min &= kernel_layer.address_mask |
| 260 | + modules_addr_max &= kernel_layer.address_mask |
| 261 | + |
240 | 262 | original_sections = {} |
241 | 263 | for index, section in enumerate(module.get_sections()): |
| 264 | + # Extra sanity check, to prevent OOM on heavily smeared samples at line |
| 265 | + # "size = next_address - address" |
| 266 | + if ( |
| 267 | + not modules_addr_min |
| 268 | + <= kernel_layer.address_mask & section.address |
| 269 | + < modules_addr_max |
| 270 | + ): |
| 271 | + continue |
242 | 272 | name = section.get_name() |
243 | 273 | original_sections[section.address] = name |
244 | 274 |
|
245 | 275 | if not original_sections: |
246 | 276 | return None |
247 | 277 |
|
248 | | - kernel = context.modules[vmlinux_name] |
249 | | - kernel_layer = context.layers[kernel.layer_name] |
250 | | - |
251 | 278 | if symbols.symbol_table_is_64bit(context, kernel.symbol_table_name): |
252 | 279 | sym_type = "Elf64_Sym" |
253 | 280 | elf_hdr_type = "Elf64_Ehdr" |
|
0 commit comments