mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-13 05:07:38 +02:00
Swap TranslationLayerInterface decendents over to LinearMappedLayers
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user