Files
volatility3/volatility/framework/layers/physical.py
T

91 lines
3.3 KiB
Python

"""
Created on 6 May 2013
@author: mike
"""
import os.path
from volatility.framework import interfaces, exceptions
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):
interfaces.layers.DataLayerInterface.__init__(self, 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):
"""Returns the smallest available address in the space"""
return 0
def is_valid(self, offset):
"""Returns whether the offset is valid or not"""
return self.minimum_address <= 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):]
class FileLayer(interfaces.layers.DataLayerInterface):
"""a DataLayer backed by a file on the filesystem"""
def __init__(self, context, name, filename):
interfaces.layers.DataLayerInterface.__init__(self, context, name)
self._file = open(filename, "r+b")
self._size = os.path.getsize(filename)
@property
def maximum_address(self):
"""Returns the largest available address in the space"""
# Zero based, so we return the size of the file minus 1
return self._size - 1
@property
def minimum_address(self):
"""Returns the smallest available address in the space"""
return 0
def is_valid(self, offset):
"""Returns whether the offset is valid or not"""
return self.minimum_address <= offset <= self.maximum_address
def read(self, offset, length, pad = False):
"""Reads from the file at offset for length"""
if not self.is_valid(offset):
raise exceptions.InvalidAddressException("Offset outside of the " + self.name + " file boundaries")
if not self.is_valid(offset + (length - 1)):
raise exceptions.InvalidAddressException("Final offset outside of the " + self.name + " file boundaries")
if length < 0:
raise TypeError("Length must be positive")
self._file.seek(offset)
data = self._file.read(length)
if len(data) < length:
if pad:
data += (b"\x00" * (length - len(data)))
else:
raise exceptions.InvalidAddressException("Could not read sufficient bytes from the " +
self.name + " file")
return data
def write(self, offset, data):
"""Writes to the file
This will technically 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)
self._file.write(data)