mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-31 12:19:42 +02:00
83 lines
3.0 KiB
Python
83 lines
3.0 KiB
Python
'''
|
|
Created on 4 May 2013
|
|
|
|
@author: mike
|
|
'''
|
|
|
|
from volatility.framework import validity, exceptions
|
|
from volatility.framework.interfaces import layers
|
|
|
|
class Memory(validity.ValidityRoutines):
|
|
"""Container for multiple layers of data"""
|
|
|
|
def __init__(self):
|
|
self._layers = {}
|
|
|
|
def read(self, layer, offset, length, pad = False):
|
|
"""Reads from a particular layer at offset for length bytes"""
|
|
return self[layer].read(offset, length, pad)
|
|
|
|
def write(self, layer, offset, data):
|
|
"""Writes to a particular layer at offset for length bytes"""
|
|
self[layer].write(offset, data)
|
|
|
|
def add_layer(self, layer):
|
|
"""Adds a layer to memory model
|
|
|
|
This will throw an exception if the required dependencies are not met
|
|
"""
|
|
self.type_check(layer, layers.DataLayerInterface)
|
|
if isinstance(layer, layers.TranslationLayerInterface):
|
|
if layer.name in self._layers:
|
|
raise exceptions.LayerException("")
|
|
missing_list = [sublayer for sublayer in layer.dependencies if sublayer not in self._layers]
|
|
if missing_list:
|
|
raise exceptions.LayerException("Layer " + layer.name + " has unmet dependencies of " + ", ".join(missing_list))
|
|
self._layers[layer.name] = layer
|
|
|
|
def del_layer(self, name):
|
|
"""Removes the layer called name
|
|
|
|
This will throw an exception if other layers depend upon this layer
|
|
"""
|
|
for layer in self._layers:
|
|
depend_list = [superlayer for superlayer in self._layers if name in superlayer.dependencies]
|
|
if depend_list:
|
|
raise exceptions.LayerException("Layer " + layer.name + " is depended upon by " + ", ".join(depend_list))
|
|
del self._layers[name]
|
|
|
|
def __getitem__(self, name):
|
|
"""Returns the layer of specified name"""
|
|
return self._layers[name]
|
|
|
|
def check_cycles(self):
|
|
"""Runs through the available layers and identifies if there are cycles in the DAG"""
|
|
|
|
class BufferDataLayer(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)
|
|
self._buffer = self.type_check(buffer, bytes)
|
|
|
|
@property
|
|
def maximum_address(self):
|
|
"""Returns the largest available address in the space"""
|
|
return len(self._buffer) - 1
|
|
|
|
@property
|
|
def minimum_address(self):
|
|
return 0
|
|
|
|
def is_valid(self, offset):
|
|
return (offset >= self.minimum_address and offset <= self.maximum_address)
|
|
|
|
def read(self, address, length, pad = False):
|
|
"""Reads the data from the buffer"""
|
|
return self._buffer[address:address + length]
|
|
|
|
def write(self, address, data):
|
|
"""Writes the data from to the buffer"""
|
|
self.type_check(data, bytes)
|
|
self._buffer = self._buffer[:address] + data + self._buffer[address + len(data):]
|