Swap TranslationLayerInterface decendents over to LinearMappedLayers

This commit is contained in:
Mike Auty
2019-08-27 21:09:13 +01:00
committed by ikelos
parent 79cb7a28f6
commit 42b2fb120a
7 changed files with 14 additions and 71 deletions
+1 -1
View File
@@ -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
+2 -1
View File
@@ -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
+3 -2
View File
@@ -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',
+2 -1
View File
@@ -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,
+2 -63
View File
@@ -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
@@ -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):
@@ -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)