From 811858aba8b67029d938f63b62dccc2bacc72475 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Wed, 31 Dec 2014 04:25:11 +0000 Subject: [PATCH] Fix metaclass usage in python 3, and fill in some missing requirements. --- volatility/framework/interfaces/context.py | 3 +-- volatility/framework/interfaces/layers.py | 8 +++---- volatility/framework/interfaces/objects.py | 23 ++++++++++++++++++-- volatility/framework/interfaces/plugins.py | 3 +-- volatility/framework/interfaces/renderers.py | 4 +--- volatility/framework/layers/intel.py | 19 ++++++++++++++++ 6 files changed, 47 insertions(+), 13 deletions(-) diff --git a/volatility/framework/interfaces/context.py b/volatility/framework/interfaces/context.py index 3b2d4890d..347f36976 100644 --- a/volatility/framework/interfaces/context.py +++ b/volatility/framework/interfaces/context.py @@ -6,12 +6,11 @@ Created on 6 May 2013 from abc import ABCMeta, abstractmethod, abstractproperty -class ContextInterface(object): +class ContextInterface(object, metaclass = ABCMeta): """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""" diff --git a/volatility/framework/interfaces/layers.py b/volatility/framework/interfaces/layers.py index f8725263e..8d91abc82 100644 --- a/volatility/framework/interfaces/layers.py +++ b/volatility/framework/interfaces/layers.py @@ -10,9 +10,8 @@ from volatility.framework.interfaces import context as context_module from abc import ABCMeta, abstractmethod, abstractproperty -class DataLayerInterface(validity.ValidityRoutines): +class DataLayerInterface(validity.ValidityRoutines, metaclass = ABCMeta): """A Layer that directly holds data (and does not translate it""" - __metaclass__ = ABCMeta def __init__(self, context, name): self._type_check(name, str) @@ -54,7 +53,7 @@ class DataLayerInterface(validity.ValidityRoutines): """ -class TranslationLayerInterface(DataLayerInterface): +class TranslationLayerInterface(DataLayerInterface, metaclass = ABCMeta): @abstractmethod def translate(self, offset): """Returns a tuple of (offset, layer) indicating the translation of input domain to the output range""" @@ -67,7 +66,8 @@ class TranslationLayerInterface(DataLayerInterface): """ return [] - @abstractproperty + @property + @abstractmethod def dependencies(self): """Returns a list of layer names that this layer translates onto""" return [] diff --git a/volatility/framework/interfaces/objects.py b/volatility/framework/interfaces/objects.py index 454d669ac..c385d1d53 100644 --- a/volatility/framework/interfaces/objects.py +++ b/volatility/framework/interfaces/objects.py @@ -11,9 +11,8 @@ from volatility.framework import validity from volatility.framework.interfaces import context as context_module -class ObjectInterface(validity.ValidityRoutines): +class ObjectInterface(validity.ValidityRoutines, metaclass = ABCMeta): """ 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, @@ -40,6 +39,26 @@ class ObjectInterface(validity.ValidityRoutines): object_template = self._context.symbol_space.resolve(new_structure_name) return object_template(context = self._context, layer_name = self._layer_name, offset = self._offset) + @classmethod + @abstractmethod + def template_replace_child(cls, old_child, new_child, arguments): + """Substitutes the old_child for the new_child""" + + @classmethod + @abstractmethod + def template_size(cls, arguments): + """Returns the size of the template object""" + + @classmethod + @abstractmethod + def template_children(cls, arguments): + """Returns the children of the template""" + + @classmethod + @abstractmethod + def template_relative_child_offset(cls, arguments, child): + """Returns the relative offset from the head of the parent data to the child member""" + class Template(object): """Class for all Factories that take offsets, and data layers and produce objects diff --git a/volatility/framework/interfaces/plugins.py b/volatility/framework/interfaces/plugins.py index 4aa45be6a..5e962d2aa 100644 --- a/volatility/framework/interfaces/plugins.py +++ b/volatility/framework/interfaces/plugins.py @@ -21,9 +21,8 @@ from volatility.framework.interfaces import context as context_module # The plugin accepts the context and modifies as necessary # The plugin runs and produces a TreeGrid output -class PluginInterface(validity.ValidityRoutines): +class PluginInterface(validity.ValidityRoutines, metaclass = ABCMeta): """Class that defines the interface all Plugins must maintain""" - __metaclass__ = ABCMeta def __init__(self, context): self._type_check(context, context_module.ContextInterface) diff --git a/volatility/framework/interfaces/renderers.py b/volatility/framework/interfaces/renderers.py index e0d783400..b3c92fdd3 100644 --- a/volatility/framework/interfaces/renderers.py +++ b/volatility/framework/interfaces/renderers.py @@ -6,9 +6,7 @@ from volatility.framework import validity __author__ = 'mike' -class Renderer(validity.ValidityRoutines): - __metaclass__ = ABCMeta - +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 diff --git a/volatility/framework/layers/intel.py b/volatility/framework/layers/intel.py index b1e4ef0dc..c9f46c103 100644 --- a/volatility/framework/layers/intel.py +++ b/volatility/framework/layers/intel.py @@ -12,6 +12,7 @@ from volatility.framework import interfaces, exceptions class Intel(interfaces.layers.TranslationLayerInterface): """Translation Layer for the Intel IA32 memory mapping""" + minimum_address = 0 def __init__(self, context, name, memory_layer, page_map_offset): interfaces.layers.TranslationLayerInterface.__init__(self, context, name) @@ -29,6 +30,10 @@ class Intel(interfaces.layers.TranslationLayerInterface): self._structure = [('page directory', 10, False), ('page table', 10, True)] + @property + def maximum_address(self): + return (2 ** self._maxvirtaddr) - 1 + @staticmethod def _mask(value, high_bit, low_bit): """Returns the bits of a value between highbit and lowbit inclusive""" @@ -83,6 +88,14 @@ class Intel(interfaces.layers.TranslationLayerInterface): page = self._mask(entry, self._maxphyaddr - 1, position + 1) | self._mask(offset, position, 0) return page, 1 << (position + 1) + def is_valid(self, offset): + """Returns whether the address offset can be translated to a valid address""" + try: + self._traslate(offset) + except exceptions.InvalidAddressException: + return False + return True + def translate(self, offset): """Translates a specific offset based on the paging tables""" result, _ = self._translate(offset) @@ -102,6 +115,12 @@ class Intel(interfaces.layers.TranslationLayerInterface): offset += chunk_size return result + @property + def dependencies(self): + """Returns a list of the lower layers that this layer is dependent upon""" + # TODO: Add in the whole buffalo + return [self._base_layer] + class IntelPAE(Intel): """Class for handling Physical Address Extensions for Intel architectures"""