# This file is Copyright 2022 Volatility Foundation and licensed under the Volatility Software License 1.0
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
#
from volatility3.framework import interfaces, constants, configuration
[docs]class KernelModule(interfaces.automagic.AutomagicInterface):
"""Finds ModuleRequirements and ensures their layer, symbols and offsets"""
priority = 100
def __call__(self,
context: interfaces.context.ContextInterface,
config_path: str,
requirement: interfaces.configuration.RequirementInterface,
progress_callback: constants.ProgressCallback = None) -> None:
new_config_path = interfaces.configuration.path_join(config_path, requirement.name)
if not isinstance(requirement, configuration.requirements.ModuleRequirement):
# Check subrequirements
for req in requirement.requirements:
self(context, new_config_path, requirement.requirements[req], progress_callback)
return
if not requirement.unsatisfied(context, config_path):
return
# The requirement is unfulfilled and is a ModuleRequirement
context.config[interfaces.configuration.path_join(
new_config_path, 'class')] = 'volatility3.framework.contexts.Module'
for req in requirement.requirements:
if requirement.requirements[req].unsatisfied(context, new_config_path) and req != 'offset':
return
# We now just have the offset requirement, but the layer requirement has been fulfilled.
# Unfortunately we don't know the layer name requirement's exact name
for req in requirement.requirements:
if isinstance(requirement.requirements[req], configuration.requirements.TranslationLayerRequirement):
layer_kvo_config_path = interfaces.configuration.path_join(new_config_path, req,
'kernel_virtual_offset')
offset_config_path = interfaces.configuration.path_join(new_config_path, 'offset')
offset = context.config[layer_kvo_config_path]
context.config[offset_config_path] = offset
# Now construct the module based on the sub-requirements
requirement.construct(context, config_path)