diff --git a/volatility/framework/automagic/stacker.py b/volatility/framework/automagic/stacker.py index 6f3398889..bcd544dc3 100644 --- a/volatility/framework/automagic/stacker.py +++ b/volatility/framework/automagic/stacker.py @@ -24,11 +24,11 @@ class LayerStacker(interfaces.automagic.AutomagicInterface): self.local_store = self.location.path new_context = context.clone() - current_layer = context.memory.free_layer_name() - # This must be specific to get us started - new_context.add_layer( - physical.FileLayer(new_context, interfaces.configuration.path_join("automagic_general", current_layer), - current_layer, self.local_store)) + current_layer_name = context.memory.free_layer_name() + current_config_path = interfaces.configuration.path_join("automagic_general", current_layer_name) + # This must be specific to get us started, setup the config and run + new_context.config[interfaces.configuration.path_join(current_config_path, "filename")] = self.local_store + new_context.add_layer(physical.FileLayer(new_context, current_config_path, current_layer_name)) # Repeatedly apply "determine what this is" code and build as much up as possible stacked = True @@ -42,15 +42,16 @@ class LayerStacker(interfaces.automagic.AutomagicInterface): for stacker_cls in stack_set: stacker = stacker_cls() try: - new_layer = stacker.stack(new_context, current_layer) + new_layer = stacker.stack(new_context, current_layer_name) + new_context.memory.add_layer(new_layer) break except Exception as excp: pass else: stacked = False if new_layer and stacker_cls: - stacked_layers = [new_layer] + stacked_layers - current_layer = new_layer + stacked_layers = [new_layer.name] + stacked_layers + current_layer_name = new_layer.name stacked = True stack_set.remove(stacker_cls) diff --git a/volatility/framework/automagic/windows.py b/volatility/framework/automagic/windows.py index 6a6b770bd..e84e0b4e6 100644 --- a/volatility/framework/automagic/windows.py +++ b/volatility/framework/automagic/windows.py @@ -183,15 +183,17 @@ class IntelHelper(interfaces.automagic.AutomagicInterface, interfaces.automagic. 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 + layer = None for test, dtb in hits: - new_layer = context.memory.free_layer_name("IntelLayer") + new_layer_name = context.memory.free_layer_name("IntelLayer") + config_path = interfaces.configuration.path_join("IntelHelper", new_layer_name) + context.config[interfaces.configuration.path_join(config_path, "memory_layer")] = layer_name + context.config[interfaces.configuration.path_join(config_path, "page_map_offset")] = dtb layer = test.layer_type(context, - config_path = interfaces.configuration.path_join("IntelHelper", new_layer), - name = new_layer, - page_map_offset = dtb) + config_path = config_path, + name = new_layer_name) break - return new_layer + return layer if __name__ == '__main__': @@ -215,10 +217,11 @@ if __name__ == '__main__': nativelst = native.x86NativeTable ctx = contexts.Context(nativelst) for filename in args.filenames: + ctx.config[ + interfaces.configuration.path_join('config' + str(args.filenames.index(filename)), "filename")] = filename data = layers.physical.FileLayer(ctx, 'config' + str(args.filenames.index(filename)), - 'data' + str(args.filenames.index(filename)), - filename = filename) + 'data' + str(args.filenames.index(filename))) ctx.memory.add_layer(data) tests = [] diff --git a/volatility/framework/interfaces/configuration.py b/volatility/framework/interfaces/configuration.py index 9ce843b25..053517ce3 100644 --- a/volatility/framework/interfaces/configuration.py +++ b/volatility/framework/interfaces/configuration.py @@ -163,11 +163,6 @@ class ConstructableRequirementInterface(RequirementInterface): if requirement_dict is None: requirement_dict = {} - node_config = context.config.branch(config_path) - # Construct the class - for req in cls.get_requirements(): - if req.name in node_config.data and req.name != "class": - requirement_dict[req.name] = node_config.data[req.name] # Fulfillment must happen, exceptions happening here mean the requirements aren't correct # and these need to be raised and fixed, rather than caught and ignored obj = cls(**requirement_dict) @@ -184,6 +179,12 @@ class ConfigurableInterface(validity.ValidityRoutines, metaclass = ABCMeta): self._context = self._check_type(context, ContextInterface) self._config_path = self._check_type(config_path, str) + # Store these programmatically, so we don't keep repreating the requirements + # This also allows constructed objects to populate a configuration without too much trouble + for requirement in self.get_requirements(): + # Create the (private) properties using the config as backend storage + setattr(self, "_" + requirement.name, self.config.get(requirement.name, requirement.default)) + @property def context(self): return self._context @@ -192,6 +193,10 @@ class ConfigurableInterface(validity.ValidityRoutines, metaclass = ABCMeta): def config_path(self): return self._config_path + @config_path.setter + def config_path(self, value): + self._config_path = self._check_type(value, str) + @property def config(self): return self._context.config.branch(self._config_path) diff --git a/volatility/framework/layers/intel.py b/volatility/framework/layers/intel.py index 944412161..025ffaf88 100644 --- a/volatility/framework/layers/intel.py +++ b/volatility/framework/layers/intel.py @@ -19,10 +19,10 @@ class Intel(interfaces.layers.TranslationLayerInterface): "architecture": "ia32" } - def __init__(self, context, config_path, name, page_map_offset, memory_layer, swap_layer = None): + def __init__(self, context, config_path, name): super().__init__(context, config_path, name) - self._base_layer = self._check_type(memory_layer, str) - self._page_map_offset = self._check_type(page_map_offset, int) + self._base_layer = self._check_type(self.config["memory_layer"], str) + self._page_map_offset = self._check_type(self.config["page_map_offset"], int) # All Intel address spaces work on 4096 byte pages self._page_size_in_bits = 12 diff --git a/volatility/framework/layers/physical.py b/volatility/framework/layers/physical.py index f117afba8..7bac74b5c 100644 --- a/volatility/framework/layers/physical.py +++ b/volatility/framework/layers/physical.py @@ -63,16 +63,16 @@ class FileLayer(interfaces.layers.DataLayerInterface): provides = {"type": "physical"} priority = 20 - def __init__(self, context, config_path, name, filename): + def __init__(self, context, config_path, name): super().__init__(context, config_path, name) - self._filename = filename + self._filename = self.config["filename"] self._file_ = None - self._size = os.path.getsize(filename) + self._size = os.path.getsize(self._filename) @property def _file(self): - """Property to prevent the intializer storing an unserializable open file (for context cloning)""" + """Property to prevent the initializer storing an unserializable open file (for context cloning)""" # FIXME: Add "+" to the mode once we've determined whether write mode is enabled mode = "rb" if not self._file_: