From 7648c9408313f25cd256a731992cc22c6c039bdb Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Mon, 22 Aug 2016 00:00:21 +0100 Subject: [PATCH] Add in the intial works at a stacking plugin to emulate volatility 2 address space stacking. --- volatility/framework/automagic/__init__.py | 1 + volatility/framework/automagic/windows.py | 36 +++++++++++--------- volatility/framework/interfaces/automagic.py | 26 ++++++++++++-- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/volatility/framework/automagic/__init__.py b/volatility/framework/automagic/__init__.py index 1ef748ab0..24a6e7775 100644 --- a/volatility/framework/automagic/__init__.py +++ b/volatility/framework/automagic/__init__.py @@ -1,6 +1,7 @@ import sys from volatility.framework import class_subclasses, import_files, interfaces +from volatility.framework.automagic import construct_layers, stacker, windows from volatility.framework.configuration import MultiRequirement diff --git a/volatility/framework/automagic/windows.py b/volatility/framework/automagic/windows.py index 0053cd5d0..6a6b770bd 100644 --- a/volatility/framework/automagic/windows.py +++ b/volatility/framework/automagic/windows.py @@ -6,7 +6,7 @@ if __name__ == "__main__": import struct -from volatility.framework import automagic, interfaces, layers, validity +from volatility.framework import interfaces, layers, validity from volatility.framework.configuration import requirements PAGE_SIZE = 0x1000 @@ -142,12 +142,10 @@ class PageMapScanner(interfaces.layers.ScannerInterface): yield (test, result) -class PageMapOffsetHelper(interfaces.automagic.AutomagicInterface): +class IntelHelper(interfaces.automagic.AutomagicInterface, interfaces.automagic.StackerLayerInterface): priority = 20 - - def __init__(self): - super().__init__() - self.tests = [DtbTest32bit(), DtbTest64bit(), DtbTestPae()] + stack_order = 90 + tests = [DtbTest32bit(), DtbTest64bit(), DtbTestPae()] def branch_leave(self, node, config_path): """Ensure we're called on internal nodes as well as external""" @@ -157,17 +155,9 @@ class PageMapOffsetHelper(interfaces.automagic.AutomagicInterface): def __call__(self, context, config_path, requirement): useful = [] sub_config_path = interfaces.configuration.path_join(config_path, requirement.name) - if isinstance(requirement, requirements.TranslationLayerRequirement): + if (isinstance(requirement, requirements.TranslationLayerRequirement) and + requirement.requirements.get("class", None)): class_req = requirement.requirements["class"] - if not class_req.validate(context, sub_config_path): - # All the intel spaces require the same kind of parameters, so pick one for the requirements - context.config.branch(config_path) - automagic.run(context, layers.intel.Intel, - interfaces.configuration.path_join(config_path, requirement.name)) - - # If a class hasn't been chosen, look through the underlying config for appropriate parameters - # If possible run scan and choose an appropriate class - pass for test in self.tests: if (test.layer_type.__module__ + "." + test.layer_type.__name__ == @@ -189,6 +179,20 @@ class PageMapOffsetHelper(interfaces.automagic.AutomagicInterface): for subreq in requirement.requirements.values(): self(context, sub_config_path, subreq) + @classmethod + def stack(cls, context, layer_name): + """Attempts to determine and stack an intel layer on a physical layer where possible""" + hits = context.memory[layer_name].scan(context, PageMapScanner(cls.tests)) + new_layer = None + for test, dtb in hits: + new_layer = context.memory.free_layer_name("IntelLayer") + layer = test.layer_type(context, + config_path = interfaces.configuration.path_join("IntelHelper", new_layer), + name = new_layer, + page_map_offset = dtb) + break + return new_layer + if __name__ == '__main__': import argparse diff --git a/volatility/framework/interfaces/automagic.py b/volatility/framework/interfaces/automagic.py index b58f46504..596976160 100644 --- a/volatility/framework/interfaces/automagic.py +++ b/volatility/framework/interfaces/automagic.py @@ -8,9 +8,29 @@ class AutomagicInterface(validity.ValidityRoutines, metaclass = ABCMeta): priority = 10 - def __init__(self): - super().__init__() - @abstractmethod def __call__(self, context, config_path, configurable): """Runs the automagic over the configurable""" + + +class StackerLayerInterface(validity.ValidityRoutines, metaclass = ABCMeta): + """Class that takes a lower layer and attempts to build on it + + stack_order determines the order (from low to high) that stacking layers + should be attempted lower levels should have lower stack_orders + """ + + stack_order = 0 + + @classmethod + @abstractmethod + def stack(self, context, layer_name): + """Method to determine whether this builder can operate on the named layer, + If so, modify the context appropriately. + + Returns the name of any new_layer stacked on top of this layer or None + The stacking is therefore strictly linear rather than tree driven. + + Configuration options provided by the context are ignored, and defaults + are to be used by this method to build a space where possible + """