diff --git a/volatility3/framework/automagic/__init__.py b/volatility3/framework/automagic/__init__.py index a10b526d2..626126c8c 100644 --- a/volatility3/framework/automagic/__init__.py +++ b/volatility3/framework/automagic/__init__.py @@ -21,11 +21,13 @@ from volatility3.framework.configuration import requirements vollog = logging.getLogger(__name__) -windows_automagic = ['ConstructionMagic', 'LayerStacker', 'WintelHelper', 'KernelPDBScanner', 'WinSwapLayers'] +windows_automagic = [ + 'ConstructionMagic', 'LayerStacker', 'WintelHelper', 'KernelPDBScanner', 'WinSwapLayers', 'KernelModule' +] -linux_automagic = ['ConstructionMagic', 'LayerStacker', 'LinuxBannerCache', 'LinuxSymbolFinder'] +linux_automagic = ['ConstructionMagic', 'LayerStacker', 'LinuxBannerCache', 'LinuxSymbolFinder', 'KernelModule'] -mac_automagic = ['ConstructionMagic', 'LayerStacker', 'MacBannerCache', 'MacSymbolFinder'] +mac_automagic = ['ConstructionMagic', 'LayerStacker', 'MacBannerCache', 'MacSymbolFinder', 'KernelModule'] def available(context: interfaces.context.ContextInterface) -> List[interfaces.automagic.AutomagicInterface]: diff --git a/volatility3/framework/automagic/linux.py b/volatility3/framework/automagic/linux.py index 767dd3407..f9fa22c07 100644 --- a/volatility3/framework/automagic/linux.py +++ b/volatility3/framework/automagic/linux.py @@ -79,7 +79,8 @@ class LinuxIntelStacker(interfaces.automagic.StackerLayerInterface): layer = layer_class(context, config_path = config_path, name = new_layer_name, - metadata = {'kaslr_value': aslr_shift, 'os': 'Linux'}) + metadata = {'os': 'Linux'}) + layer.config['kernel_virtual_offset'] = aslr_shift if layer and dtb: vollog.debug(f"DTB was found at: 0x{dtb:0x}") diff --git a/volatility3/framework/automagic/mac.py b/volatility3/framework/automagic/mac.py index 07c995b36..fb725a234 100644 --- a/volatility3/framework/automagic/mac.py +++ b/volatility3/framework/automagic/mac.py @@ -105,7 +105,8 @@ class MacIntelStacker(interfaces.automagic.StackerLayerInterface): new_layer = intel.Intel32e(context, config_path = config_path, name = new_layer_name, - metadata = {'kaslr_value': kaslr_shift}) + metadata = {'os': 'mac'}) + new_layer.config['kernel_virtual_offset'] = kaslr_shift if new_layer and dtb: vollog.debug(f"DTB was found at: 0x{dtb:0x}") diff --git a/volatility3/framework/automagic/module.py b/volatility3/framework/automagic/module.py new file mode 100644 index 000000000..315164ec7 --- /dev/null +++ b/volatility3/framework/automagic/module.py @@ -0,0 +1,48 @@ +from volatility3.framework import interfaces, constants, configuration + + +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.ConfigurableModule' + + 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 + elif isinstance(requirement.requirements[req], configuration.requirements.SymbolTableRequirement): + symbol_shift_config_path = interfaces.configuration.path_join(new_config_path, + req, + 'symbol_shift') + context.config[symbol_shift_config_path] = 0 + + # Now construct the module based on the sub-requirements + requirement.construct(context, config_path)