Rename the SCHEMA_NAME_DIVIDER, and ensure all paths are flat strings.

This commit is contained in:
Mike Auty
2016-01-12 23:44:55 +00:00
parent 629dfe2653
commit 415a0948a0
4 changed files with 18 additions and 28 deletions
+1 -1
View File
@@ -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()
@@ -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:
+5 -4
View File
@@ -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
@@ -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