From 26caf31974b2cce4ba929b009f8ed830c5b48f47 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Wed, 8 May 2013 19:17:21 +0100 Subject: [PATCH] Revisit the decision to try out super, and decide to stick with specific inheritance to avoid **kwargs everywhere. --- volatility/framework/__init__.py | 2 +- volatility/framework/interfaces/layers.py | 41 +++++++++++++++-- volatility/framework/layers/physical.py | 9 ++-- volatility/framework/objects/__init__.py | 54 ++++++++++++----------- volatility/framework/objects/templates.py | 2 +- volatility/framework/symbols/native.py | 2 +- volatility/framework/symbols/vtypes.py | 2 +- 7 files changed, 77 insertions(+), 35 deletions(-) diff --git a/volatility/framework/__init__.py b/volatility/framework/__init__.py index 76427cb6e..c36e883f6 100644 --- a/volatility/framework/__init__.py +++ b/volatility/framework/__init__.py @@ -34,7 +34,7 @@ class Context(interfaces.context.ContextInterface): """Maintains the context within which to construct objects""" def __init__(self, natives): - super(Context, self).__init__() + interfaces.context.ContextInterface.__init__(self) self._symbol_space = symbols.SymbolSpace(natives) self._memory = layers.Memory() diff --git a/volatility/framework/interfaces/layers.py b/volatility/framework/interfaces/layers.py index 16fa70bb9..c88524d87 100644 --- a/volatility/framework/interfaces/layers.py +++ b/volatility/framework/interfaces/layers.py @@ -4,7 +4,7 @@ Created on 4 May 2013 @author: mike ''' -from volatility.framework import validity +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 @@ -32,7 +32,7 @@ class DataLayerInterface(validity.ValidityRoutines): """Returns a boolean based on whether the offset is valid or not""" def read(self, offset, length, pad = False): - """Read takes an offset and a size and returns 'bytes' (not 'str') of length size + """Reads an offset for length bytes and returns 'bytes' (not 'str') of length size If there is a fault of any kind (such as a pagefault), an exception will be thrown unless pad is set, in which case the read errors will be replaced by null characters. @@ -51,7 +51,42 @@ class TranslationLayerInterface(DataLayerInterface): """Returns a tuple of (offset, layer) indicating the translation of input domain to the output range""" def mapping(self, offset, length): - """Returns a list of (offset, length, layer) mappings""" + """Returns a sorted list of (offset, mapped_offset, length, layer) mappings + + This allows translation layers to provide maps of contiguous regions in one layer + """ def dependencies(self): """Returns a list of layer names that this layer translates onto""" + + ### Read/Write functions for mapped pages + + def read(self, offset, length, pad = False): + """Reads an offset for length bytes and returns 'bytes' (not 'str') of length size""" + current_offset = offset + 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) + elif offset > current_offset: + output += b"\x00" * (current_offset - offset) + current_offset = offset + elif offset < current_offset: + raise exceptions.LayerException("Mapping returned an overlapping element") + output += self._context.memory.read(mapped_offset, length, layer, pad) + current_offset += length + return output + + def write(self, offset, value): + """Writes a value at offset, distributing the writing across any underlying mapping""" + current_offset = offset + length = len(value) + for (offset, mapped_offset, length, layer) in self.mapping(offset, length): + if offset > current_offset: + raise exceptions.InvalidAddressException("Layer " + self.name + " cannot map offset " + current_offset) + elif offset < current_offset: + raise exceptions.LayerException("Mapping returned an overlapping element") + self._context.memory.write(mapped_offset, length, layer) + current_offset += length + + diff --git a/volatility/framework/layers/physical.py b/volatility/framework/layers/physical.py index 2e5557ec7..6f9fb75e2 100644 --- a/volatility/framework/layers/physical.py +++ b/volatility/framework/layers/physical.py @@ -11,7 +11,7 @@ class BufferDataLayer(interfaces.layers.DataLayerInterface): """A DataLayer class backed by a buffer in memory, designed for testing and swift data access""" def __init__(self, context, name, buffer): - super(BufferDataLayer, self).__init__(context, name) + interfaces.layers.DataLayerInterface.__init__(self, context, name) self._buffer = self.type_check(buffer, bytes) @property @@ -41,7 +41,7 @@ class FileLayer(interfaces.layers.DataLayerInterface): """a DataLayer backed by a file on the filesystem""" def __init__(self, context, name, filename): - super(FileLayer, self).__init__(context, name) + interfaces.layers.DataLayerInterface.__init__(self, context, name) self._file = open(filename, "r+b") self._size = os.path.getsize(filename) @@ -79,7 +79,10 @@ class FileLayer(interfaces.layers.DataLayerInterface): return data def write(self, offset, data): - """Writes to the file""" + """Writes to the file + + This will tehcnically allow writes beyond the extent of the file + """ if not self.is_valid(offset): raise exceptions.InvalidAddressException("Offset outside of the " + self.name + " file boundaries") self._file.seek(offset) diff --git a/volatility/framework/objects/__init__.py b/volatility/framework/objects/__init__.py index 4c6d9d416..dde7f4608 100644 --- a/volatility/framework/objects/__init__.py +++ b/volatility/framework/objects/__init__.py @@ -29,12 +29,13 @@ class PrimitiveObject(interfaces.objects.ObjectInterface): """PrimitiveObject is an interface for any objects that should simulate a Python primitive""" def __init__(self, context, layer_name, offset, symbol_name, size = None, parent = None, struct_format = '