Source code for volatility3.plugins.linux.module_extract
# This file is Copyright 2025 Volatility Foundation and licensed under the Volatility Software License 1.0
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
#
import logging
from typing import List
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
from volatility3 import framework
from volatility3.framework import interfaces, renderers
from volatility3.framework.configuration import requirements
from volatility3.framework.renderers import format_hints
from volatility3.framework.objects import utility
vollog = logging.getLogger(__name__)
[docs]
class ModuleExtract(interfaces.plugins.PluginInterface):
"""Recreates an ELF file from a specific address in the kernel"""
_version = (1, 0, 1)
_required_framework_version = (2, 25, 0)
framework.require_interface_version(*_required_framework_version)
[docs]
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(
name="kernel",
description="Windows kernel",
architectures=["Intel32", "Intel64"],
),
requirements.IntRequirement(
name="base",
description="Base virtual address to reconstruct an ELF file",
optional=False,
),
requirements.VersionRequirement(
name="linux_utilities_modules_module_extract",
version=(1, 0, 2),
component=linux_utilities_modules.ModuleExtract,
),
]
def _generator(self):
kernel = self.context.modules[self.config["kernel"]]
base_address = self.config["base"]
kernel_layer = self.context.layers[kernel.layer_name]
if not kernel_layer.is_valid(base_address):
vollog.error(
f"Given base address ({base_address:#x}) is not valid in the kernel address space. Unable to extract file."
)
return
module = kernel.object(object_type="module", offset=base_address, absolute=True)
elf_data = linux_utilities_modules.ModuleExtract.extract_module(
self.context, self.config["kernel"], module
)
if not elf_data:
vollog.error(
f"Unable to reconstruct the ELF for module struct at {base_address:#x}"
)
return
module_name = utility.array_to_string(module.name)
file_name = self.open.sanitize_filename(
f"kernel_module.{module_name}.{base_address:#x}.elf"
)
with self.open(file_name) as file_handle:
file_handle.write(elf_data)
yield (
0,
(
format_hints.Hex(base_address),
len(elf_data),
file_handle.preferred_filename,
),
)
[docs]
def run(self):
return renderers.TreeGrid(
[
("Base", format_hints.Hex),
("File Size", int),
("File output", str),
],
self._generator(),
)