From 42b2fb120a73e8bdc4b1d62d5a20f4b047b70b0b Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Sun, 25 Aug 2019 13:39:07 +0100 Subject: [PATCH] Swap TranslationLayerInterface decendents over to LinearMappedLayers --- volatility/framework/layers/__init__.py | 2 +- volatility/framework/layers/intel.py | 3 +- volatility/framework/layers/msf.py | 5 +- volatility/framework/layers/registry.py | 3 +- volatility/framework/layers/segmented.py | 65 +------------------ .../framework/plugins/windows/strings.py | 4 +- .../symbols/linux/extensions/__init__.py | 3 +- 7 files changed, 14 insertions(+), 71 deletions(-) diff --git a/volatility/framework/layers/__init__.py b/volatility/framework/layers/__init__.py index 63a7c7595..7c6f7e9b8 100644 --- a/volatility/framework/layers/__init__.py +++ b/volatility/framework/layers/__init__.py @@ -18,4 +18,4 @@ # specific language governing rights and limitations under the License. # -from volatility.framework.layers import resources, intel, lime, physical, segmented, vmware, crash, msf +from volatility.framework.layers import linear, resources, intel, lime, physical, segmented, vmware, crash, msf, registry diff --git a/volatility/framework/layers/intel.py b/volatility/framework/layers/intel.py index 8deb62d23..77eaf3a75 100644 --- a/volatility/framework/layers/intel.py +++ b/volatility/framework/layers/intel.py @@ -28,11 +28,12 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple from volatility import framework, classproperty from volatility.framework import exceptions, interfaces from volatility.framework.configuration import requirements +from volatility.framework.layers import linear vollog = logging.getLogger(__name__) -class Intel(interfaces.layers.TranslationLayerInterface): +class Intel(linear.LinearlyMappedLayer): """Translation Layer for the Intel IA32 memory mapping""" priority = 40 diff --git a/volatility/framework/layers/msf.py b/volatility/framework/layers/msf.py index a9f0d5620..34cab4515 100644 --- a/volatility/framework/layers/msf.py +++ b/volatility/framework/layers/msf.py @@ -22,11 +22,12 @@ from typing import Optional, Dict, Any, List, Iterable, Tuple from volatility.framework import interfaces, constants, exceptions from volatility.framework.configuration import requirements +from volatility.framework.layers import linear from volatility.framework.objects import utility from volatility.framework.symbols import intermed -class PdbMultiStreamFormat(interfaces.layers.TranslationLayerInterface): +class PdbMultiStreamFormat(linear.LinearlyMappedLayer): _headers = { "MSF_HDR": "Microsoft C/C++ program database 2.00\r\n\x1a\x4a\x47", "BIG_MSF_HDR": "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53", @@ -157,7 +158,7 @@ class PdbMultiStreamFormat(interfaces.layers.TranslationLayerInterface): return None -class PdbMSFStream(interfaces.layers.TranslationLayerInterface): +class PdbMSFStream(linear.LinearlyMappedLayer): def __init__(self, context: 'interfaces.context.ContextInterface', diff --git a/volatility/framework/layers/registry.py b/volatility/framework/layers/registry.py index 503ad5dd4..294ec6454 100644 --- a/volatility/framework/layers/registry.py +++ b/volatility/framework/layers/registry.py @@ -25,6 +25,7 @@ from volatility.framework import constants, exceptions, interfaces, objects from volatility.framework.configuration import requirements from volatility.framework.configuration.requirements import IntRequirement, TranslationLayerRequirement from volatility.framework.exceptions import InvalidAddressException +from volatility.framework.layers import linear from volatility.framework.symbols import intermed from volatility.plugins.windows import pslist @@ -39,7 +40,7 @@ class RegistryInvalidIndex(exceptions.LayerException): """Thrown when an index that doesn't exist or can't be found occurs""" -class RegistryHive(interfaces.layers.TranslationLayerInterface): +class RegistryHive(linear.LinearlyMappedLayer): def __init__(self, context: interfaces.context.ContextInterface, diff --git a/volatility/framework/layers/segmented.py b/volatility/framework/layers/segmented.py index 1278a54a9..99739b17a 100644 --- a/volatility/framework/layers/segmented.py +++ b/volatility/framework/layers/segmented.py @@ -24,71 +24,10 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple from volatility.framework import exceptions, interfaces from volatility.framework.configuration import requirements +from volatility.framework.layers import linear -class LinearlyMappedLayer(interfaces.layers.TranslationLayerInterface): - """Class to differentiate Linearly Mapped layers (where a => b implies that a + c => b + c)""" - - ### Translation layer convenience function - - def translate(self, offset: int, ignore_errors: bool = False) -> Tuple[Optional[int], Optional[str]]: - mapping = list(self.mapping(offset, 0, ignore_errors)) - if len(mapping) == 1: - original_offset, mapped_offset, _, layer = mapping[0] - if original_offset != offset: - raise exceptions.LayerException(self.name, - "Layer {} claims to map linearly but does not".format(self.name)) - else: - if ignore_errors: - # We should only hit this if we ignored errors, but check anyway - return None, None - raise exceptions.InvalidAddressException(self.name, offset, - "Cannot translate {} in layer {}".format(offset, self.name)) - return mapped_offset, layer - - # ## Read/Write functions for mapped pages - # Redefine read here for speed reasons (so we don't call a processing method - - @functools.lru_cache(maxsize = 512) - def read(self, offset: int, length: int, pad: bool = False) -> bytes: - """Reads an offset for length bytes and returns 'bytes' (not 'str') of length size""" - current_offset = offset - output = [] # type: List[bytes] - for (offset, mapped_offset, mapped_length, layer) in self.mapping(offset, length, ignore_errors = pad): - if not pad and offset > current_offset: - raise exceptions.InvalidAddressException( - self.name, current_offset, "Layer {} cannot map offset: {}".format(self.name, current_offset)) - elif offset > current_offset: - output += [b"\x00" * (offset - current_offset)] - current_offset = offset - elif offset < current_offset: - raise exceptions.LayerException(self.name, "Mapping returned an overlapping element") - if mapped_length > 0: - output += [self._context.layers.read(layer, mapped_offset, mapped_length, pad)] - current_offset += mapped_length - recovered_data = b"".join(output) - return recovered_data + b"\x00" * (length - len(recovered_data)) - - def write(self, offset: int, value: bytes) -> None: - """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( - self.name, current_offset, "Layer {} cannot map offset: {}".format(self.name, current_offset)) - elif offset < current_offset: - raise exceptions.LayerException(self.name, "Mapping returned an overlapping element") - self._context.layers.write(layer, mapped_offset, value[:length]) - value = value[length:] - current_offset += length - - -class NonLinearlyMappedLayer(interfaces.layers.TranslationLayerInterface): - """Class to allow layers which don't map linearly to exist""" - - -class SegmentedLayer(interfaces.layers.TranslationLayerInterface, metaclass = ABCMeta): +class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): """A class to handle a single run-based layer-to-layer mapping In the documentation "mapped address" or "mapped offset" refers to an offset once it has been mapped to the underlying layer diff --git a/volatility/framework/plugins/windows/strings.py b/volatility/framework/plugins/windows/strings.py index 3565980d0..9e915256b 100644 --- a/volatility/framework/plugins/windows/strings.py +++ b/volatility/framework/plugins/windows/strings.py @@ -24,7 +24,7 @@ from typing import Dict, Generator, List, Set, Tuple from volatility.framework import interfaces, renderers from volatility.framework.configuration import requirements -from volatility.framework.layers import intel, resources +from volatility.framework.layers import intel, resources, linear from volatility.framework.renderers import format_hints from volatility.plugins.windows import pslist @@ -96,7 +96,7 @@ class Strings(interfaces.plugins.PluginInterface): self.config['nt_symbols']): proc_layer_name = process.add_process_layer() proc_layer = self.context.layers[proc_layer_name] - if isinstance(proc_layer, interfaces.layers.TranslationLayerInterface): + if isinstance(proc_layer, linear.LinearlyMappedLayer): for mapval in proc_layer.mapping(0x0, proc_layer.maximum_address, ignore_errors = True): kpage, vpage, page_size, maplayer = mapval for val in range(kpage, kpage + page_size, 0x1000): diff --git a/volatility/framework/symbols/linux/extensions/__init__.py b/volatility/framework/symbols/linux/extensions/__init__.py index 4bf029e34..f0d9d893f 100644 --- a/volatility/framework/symbols/linux/extensions/__init__.py +++ b/volatility/framework/symbols/linux/extensions/__init__.py @@ -26,6 +26,7 @@ import volatility.framework.objects.utility from volatility.framework import constants from volatility.framework import exceptions, objects, interfaces from volatility.framework.automagic import linux +from volatility.framework.layers import linear from volatility.framework.symbols import generic vollog = logging.getLogger(__name__) @@ -67,7 +68,7 @@ class task_struct(generic.GenericIntelProcess): except exceptions.PagedInvalidAddressException: return None - if not isinstance(parent_layer, interfaces.layers.TranslationLayerInterface): + if not isinstance(parent_layer, linear.LinearlyMappedLayer): raise TypeError("Parent layer is not a translation layer, unable to construct process layer") dtb, layer_name = parent_layer.translate(pgd)