From 415a0948a0d7fad8524eb274238e666ab54be8fb Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Tue, 12 Jan 2016 23:44:55 +0000 Subject: [PATCH] Rename the SCHEMA_NAME_DIVIDER, and ensure all paths are flat strings. --- volatility/cli/__init__.py | 2 +- .../framework/configuration/depresolver.py | 17 ++++++++--------- volatility/framework/contexts/__init__.py | 9 +++++---- .../framework/interfaces/configuration.py | 18 ++++-------------- 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/volatility/cli/__init__.py b/volatility/cli/__init__.py index 112c53bb3..5e47b93af 100644 --- a/volatility/cli/__init__.py +++ b/volatility/cli/__init__.py @@ -59,7 +59,7 @@ class CommandLine(object): ctx.config["pslist.primary.page_map_offset"] = 0x39000 ctx.config["pslist.offset"] = 0x823c87c0 - if dldr.validate_dependencies(dependencies, context = ctx, path = ["pslist"]): + if dldr.validate_dependencies(dependencies, context = ctx, path = plugin.__name__.lower()): # Construct and run the plugin plugin(ctx).run() diff --git a/volatility/framework/configuration/depresolver.py b/volatility/framework/configuration/depresolver.py index 6aeab2257..786fde15e 100644 --- a/volatility/framework/configuration/depresolver.py +++ b/volatility/framework/configuration/depresolver.py @@ -37,16 +37,18 @@ class DataLayerDependencyResolver(validity.ValidityRoutines): def validate_dependencies(self, deptree, context, path = None): """Takes a dependency tree and attempts to resolve the tree by validating each branch and using the first that successfully validates - @param path: A list of path components to access the deptree's configuration details + @param path: A path to access the deptree's configuration details """ # TODO: Simplify config system access to ensure easier code # TODO: Improve logging/output of this code to diagnose errors if path is None: - path = [] + path = "" for node in deptree: + node_path = path + configuration.CONFIG_SEPARATOR + node.requirement.name if isinstance(node, Node) and not node.requirement.optional: + node_config = context.config.branch(node_path) for branch, subtree in node.branches.items(): - if self.validate_dependencies(subtree, context, path = path + [node.requirement.name]): + if self.validate_dependencies(subtree, context, path = node_path): # Generate a layer name layer_name = node.requirement.name counter = 2 @@ -55,18 +57,15 @@ class DataLayerDependencyResolver(validity.ValidityRoutines): counter += 1 # Construct the layer - requirement_dict = dict([(n.requirement.name, context.config.get( - configuration.schema_name_join(path + [node.requirement.name, n.requirement.name]))) for - n - in subtree]) + requirement_dict = node_config context.add_layer(branch(context, layer_name, **requirement_dict)) - context.config[configuration.schema_name_join(path + [node.requirement.name])] = layer_name + context.config[node_path] = layer_name break else: return False try: print("NODE", node, "OPTIONAL", node.requirement.optional) - value = context.config[configuration.schema_name_join(path + [node.requirement.name])] + value = context.config[node_path] print("TEST", value) node.requirement.validate(value, context) except BaseException as e: diff --git a/volatility/framework/contexts/__init__.py b/volatility/framework/contexts/__init__.py index c3706fb70..ef48e0c81 100644 --- a/volatility/framework/contexts/__init__.py +++ b/volatility/framework/contexts/__init__.py @@ -1,4 +1,5 @@ from volatility.framework import interfaces, symbols, layers +from volatility.framework.interfaces.configuration import HierarchicalDict __author__ = 'mike' @@ -23,19 +24,19 @@ class Context(interfaces.context.ContextInterface): interfaces.context.ContextInterface.__init__(self) self._symbol_space = symbols.SymbolSpace(natives) self._memory = layers.Memory() - self._config = {} + self._config = HierarchicalDict(interfaces.configuration.CONFIG_SEPARATOR) # ## Symbol Space Functions @property def config(self): - """Returns the configuration object for this context""" + """Returns a mutable copy of the configuration, but does not allow the whole configuration to be altered""" return self._config @config.setter def config(self, value): - if not isinstance(value, dict): - raise TypeError("Configuration must be of type Dict") + if not isinstance(value, HierarchicalDict): + raise TypeError("Config must be of type HierarchicalDict") self._config = value @property diff --git a/volatility/framework/interfaces/configuration.py b/volatility/framework/interfaces/configuration.py index 867cbaf9d..5ba244c0a 100644 --- a/volatility/framework/interfaces/configuration.py +++ b/volatility/framework/interfaces/configuration.py @@ -1,10 +1,11 @@ +import collections from abc import ABCMeta, abstractmethod from volatility.framework import validity __author__ = 'mike' -SCHEMA_NAME_DIVIDER = "." +CONFIG_SEPARATOR = "." # Design requirements: @@ -22,25 +23,14 @@ SCHEMA_NAME_DIVIDER = "." # Dependency solver # Attempts to fill all dependencies by traversing the various available classes to find a solution - -def schema_name_join(pathlist): - """Returns the path string of a list of path components for a schema""" - return SCHEMA_NAME_DIVIDER.join(pathlist) - - -def schema_name_split(path): - """Returns the path components of a schema name""" - return path.split(SCHEMA_NAME_DIVIDER) - - class ConfigurationSchemaNode(validity.ValidityRoutines, metaclass = ABCMeta): """Class to distinguish configuration elements from everything else""" def __init__(self, name, description = None, default = None, optional = False): validity.ValidityRoutines.__init__(self) self._check_type(name, str) - if SCHEMA_NAME_DIVIDER in name: - raise ValueError("Name cannot contain the namespace divider (" + SCHEMA_NAME_DIVIDER + ")") + if CONFIG_SEPARATOR in name: + raise ValueError("Name cannot contain the config-hierarchy divider (" + CONFIG_SEPARATOR + ")") self._name = name self._description = description or "" self._default = default