Refactor the context back into the ConfigurableInterface.

This also adds support for manually constructed configurables to
populate the config tree in the current context.

I'm still toying around with this though, I need to figure out
what to do with optional values and think the whole thing through
to make sure it's worthwhile.
This commit is contained in:
Mike Auty
2016-08-14 21:28:43 +01:00
parent ce16d60eaf
commit ca61cf10b9
6 changed files with 33 additions and 15 deletions
@@ -2,6 +2,7 @@ import sys
from abc import ABCMeta, abstractmethod
from volatility.framework import validity
from volatility.framework.interfaces.context import ContextInterface
__author__ = 'mike'
@@ -166,17 +167,30 @@ class ConstructableRequirementInterface(RequirementInterface):
return obj
class ConfigurableInterface(validity.ValidityRoutines):
class ConfigurableInterface(validity.ValidityRoutines, metaclass = ABCMeta):
"""Class to allow objects to have requirements and read configuration data from the context config tree"""
def __init__(self, config_path):
def __init__(self, context, config_path):
"""Basic initializer that allows configurables to access their own config settings"""
super().__init__()
self._context = self._check_type(context, ContextInterface)
self._config_path = self._check_type(config_path, str)
@property
def context(self):
return self._context
@property
def config(self):
return self._context.config.branch(self._config_path)
@abstractmethod
def update_configuration(self):
"""Ensures that if the class has been created, its configuration is correct"""
@classmethod
def get_requirements(cls):
"""Returns a list of RequirementInterface objects required by this object"""
"""Returns a list of RequirementInterface objects required by this object"""
return []
@classmethod
+1 -2
View File
@@ -68,8 +68,7 @@ class DataLayerInterface(configuration.ConfigurableInterface, validity.ValidityR
provides = {"type": "interface"}
def __init__(self, context, config_path, name):
super().__init__(config_path)
self._context = context
super().__init__(context, config_path)
self._check_type(name, str)
self._name = name
+1 -10
View File
@@ -26,18 +26,9 @@ class PluginInterface(configuration_interface.ConfigurableInterface, validity.Va
"""Class that defines the interface all Plugins must maintain"""
def __init__(self, context, config_path):
super().__init__(config_path)
self._context = self._check_type(context, context_interface.ContextInterface)
super().__init__(context, config_path)
# self.validate()
@property
def context(self):
return self._context
@property
def config(self):
return self._context.config.branch(self._config_path)
@classmethod
def get_requirements(cls):
"""Returns a list of Requirement objects for this plugin"""
+5
View File
@@ -148,6 +148,11 @@ class Intel(interfaces.layers.TranslationLayerInterface):
requirements.IntRequirement(name = 'page_map_offset',
optional = False)]
def update_configuration(self):
self.config["class"] = self.__class__.__name__
self.config["memory_layer"] = self._base_layer
self.config["page_map_offset"] = self._page_map_offset
class IntelPAE(Intel):
"""Class for handling Physical Address Extensions for Intel architectures"""
+6
View File
@@ -56,6 +56,9 @@ class BufferDataLayer(interfaces.layers.DataLayerInterface):
return [requirements.BytesRequirement(name = 'buffer', description = "The direct bytes to interact with",
optional = False)]
def update_configuration(self):
self.config["buffer"] = self._buffer
class FileLayer(interfaces.layers.DataLayerInterface):
"""a DataLayer backed by a file on the filesystem"""
@@ -137,3 +140,6 @@ class FileLayer(interfaces.layers.DataLayerInterface):
@classmethod
def get_requirements(cls):
return [requirements.StringRequirement(name = 'filename', optional = False)]
def update_configuration(self):
self.config['filename'] = self._filename
+3
View File
@@ -16,6 +16,9 @@ class PsList(plugins.PluginInterface):
requirements.IntRequirement(name = 'offset',
description = 'Virtual address of any process')]
def update_configuration(self):
"""No operation since all values provided by config/requirements initially"""
@staticmethod
def kernel_process_from_physical_process(ctx, physical_layer, kernel_layer, offset):
"""Return a kernel process object from physical process data."""