diff --git a/volatility/framework/interfaces/context.py b/volatility/framework/interfaces/context.py index e9c589ad1..a900a37d3 100644 --- a/volatility/framework/interfaces/context.py +++ b/volatility/framework/interfaces/context.py @@ -3,24 +3,27 @@ Created on 6 May 2013 @author: mike """ - +from abc import ABCMeta, abstractmethod, abstractproperty class ContextInterface(object): - """All context-like objects must adhere to the following interface.""" + """All context-like objects must adhere to the following interface. + + This interface is present to avoid import dependency cycles. + """ + __metaclass__ = ABCMeta def __init__(self): """Initializes the context with a symbol_space""" ### Symbol Space Functions - @property + @abstractproperty def symbol_space(self): """Returns the symbol_space for the context""" - raise NotImplementedError("Symbol_space has not been implemented.") ### Memory Functions - @property + @abstractproperty def memory(self): """Returns the memory object for the context""" raise NotImplementedError("Memory has not been implemented.") @@ -31,6 +34,7 @@ class ContextInterface(object): ### Object Factory Functions + @abstractmethod def object(self, symbol, layer_name, offset): """Object factory, takes a context, symbol, offset and optional layer_name diff --git a/volatility/framework/interfaces/layers.py b/volatility/framework/interfaces/layers.py index 2520ece4d..db77ce961 100644 --- a/volatility/framework/interfaces/layers.py +++ b/volatility/framework/interfaces/layers.py @@ -7,10 +7,11 @@ Created on 4 May 2013 from volatility.framework import validity, exceptions # We can't just import interfaces because we'd have a cycle going from volatility.framework.interfaces import context as context_module - +from abc import ABCMeta, abstractmethod, abstractproperty class DataLayerInterface(validity.ValidityRoutines): """A Layer that directly holds data (and does not translate it""" + __metaclass__ = ABCMeta def __init__(self, context, name): self.type_check(name, str) @@ -23,19 +24,19 @@ class DataLayerInterface(validity.ValidityRoutines): """Returns the layer name""" return self._name - @property + @abstractproperty def maximum_address(self): """Returns the maximum valid address of the space""" - raise NotImplementedError("Maximum Address has not been implemented") - @property + @abstractproperty def minimum_address(self): """Returns the minimum valid address of the space""" - raise NotImplementedError("Minimum Address has not been implemented") + @abstractmethod def is_valid(self, offset): """Returns a boolean based on whether the offset is valid or not""" + @abstractmethod def read(self, offset, length, pad = False): """Reads an offset for length bytes and returns 'bytes' (not 'str') of length size @@ -43,6 +44,7 @@ class DataLayerInterface(validity.ValidityRoutines): unless pad is set, in which case the read errors will be replaced by null characters. """ + @abstractmethod def write(self, offset, data): """Writes a chunk of data at offset. @@ -53,9 +55,11 @@ class DataLayerInterface(validity.ValidityRoutines): class TranslationLayerInterface(DataLayerInterface): + @abstractmethod def translate(self, offset): """Returns a tuple of (offset, layer) indicating the translation of input domain to the output range""" + @abstractmethod def mapping(self, offset, length): """Returns a sorted list of (offset, mapped_offset, length, layer) mappings @@ -63,10 +67,9 @@ class TranslationLayerInterface(DataLayerInterface): """ return [] - @property + @abstractproperty def dependencies(self): """Returns a list of layer names that this layer translates onto""" - raise NotImplementedError("Abstract method dependencies") ### Read/Write functions for mapped pages @@ -76,7 +79,8 @@ class TranslationLayerInterface(DataLayerInterface): output = b"" for (offset, mapped_offset, length, layer) in self.mapping(offset, length): if not pad and offset > current_offset: - raise exceptions.InvalidAddressException("Layer " + self.name + " cannot map offset " + current_offset) + raise exceptions.InvalidAddressException("Layer " + self.name + " cannot map offset " + + str(current_offset)) elif offset > current_offset: output += b"\x00" * (current_offset - offset) current_offset = offset diff --git a/volatility/framework/interfaces/objects.py b/volatility/framework/interfaces/objects.py index 0700aef53..bf1163b7b 100644 --- a/volatility/framework/interfaces/objects.py +++ b/volatility/framework/interfaces/objects.py @@ -1,15 +1,18 @@ -''' +""" Created on 6 May 2013 @author: mike -''' +""" import copy from volatility.framework import validity from volatility.framework.interfaces import context as context_module +from abc import ABCMeta, abstractmethod class ObjectInterface(validity.ValidityRoutines): """ A base object required to be the ancestor of every object used in volatility """ + __metaclass__ = ABCMeta + def __init__(self, context, layer_name, offset, structure_name, size, parent = None): # Since objects are likely to be instantiated often, # we're only checking that context, offset and parent @@ -26,6 +29,7 @@ class ObjectInterface(validity.ValidityRoutines): self._structure_name = structure_name self._size = size + @abstractmethod def write(self, value): """Writes the new value into the format at the offset the object currently resides at""" diff --git a/volatility/framework/interfaces/plugins.py b/volatility/framework/interfaces/plugins.py index 2fc82604d..c335d0fd8 100644 --- a/volatility/framework/interfaces/plugins.py +++ b/volatility/framework/interfaces/plugins.py @@ -3,6 +3,7 @@ Created on 6 May 2013 @author: mike """ +from abc import abstractmethod, ABCMeta from volatility.framework import validity from volatility.framework.interfaces import context as context_module @@ -10,6 +11,7 @@ from volatility.framework.interfaces import context as context_module class PluginInterface(validity.ValidityRoutines): """Class that defines the interface all Plugins must maintain""" + __metaclass__ = ABCMeta def __init__(self, context): self.type_check(context, context_module.ContextInterface) @@ -19,17 +21,18 @@ class PluginInterface(validity.ValidityRoutines): def context(self): return self._context + @abstractmethod def establish_context(self): """Alters the context to ensure the plugin can run. This function constructs the necessary address spaces and symbol spaces that the plugin will need. """ - raise NotImplementedError("Abstract method establish_context must be overridden by plugins.") + @abstractmethod def plugin_options(self, config_group = None): """Modifies the passed in ConfigGroup object to contain the required options""" - raise NotImplementedError("Abstract method plugin_options must be overridden by plugins") + @abstractmethod def __call__(self, context): """Executes the functionality of the code diff --git a/volatility/framework/interfaces/renderers.py b/volatility/framework/interfaces/renderers.py index 9036b1d99..539261655 100644 --- a/volatility/framework/interfaces/renderers.py +++ b/volatility/framework/interfaces/renderers.py @@ -1,18 +1,20 @@ +from abc import abstractmethod, ABCMeta from volatility.framework import validity __author__ = 'mike' class Renderer(validity.ValidityRoutines): + __metaclass__ = ABCMeta + def __init__(self, options): """Accepts an options object to configure the renderers""" #FIXME: Once the config option objects are in place, put the type_check in place - @staticmethod - def get_render_options(): + @abstractmethod + def get_render_options(self): """Returns a list of rendering options""" - raise NotImplementedError("Abstract method get_render_options not implemented.") + @abstractmethod def render(self, grid): """Takes a grid object and renders it based on the object's preferences""" - raise NotImplementedError("Abstract method render not implemented.")