mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-28 10:49:42 +02:00
Restructure the packages, change importing style to from ... import.
This commit is contained in:
@@ -4,7 +4,7 @@ Created on 12 Feb 2013
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
import volatility.framework.interfaces as interfaces
|
||||
from volatility.framework import interfaces
|
||||
|
||||
class Context(interfaces.ContextInterface):
|
||||
"""Maintains the context within which to construct objects"""
|
||||
|
||||
@@ -5,19 +5,7 @@ Created on 12 Apr 2013
|
||||
'''
|
||||
|
||||
import copy
|
||||
|
||||
class ObjectInterface(object):
|
||||
""" A base object required to be the ancestor of every object used in volatility """
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size, **kwargs):
|
||||
self._context = context
|
||||
self._offset = offset
|
||||
self._layer_name = layer_name
|
||||
self._symbol_name = symbol_name
|
||||
self._size = size
|
||||
|
||||
def cast(self, new_symbol_name):
|
||||
object_template = self._context.resolve(new_symbol_name)
|
||||
return object_template(context = self._context, layer_name = self._layer_name, offset = self._offset)
|
||||
from volatility.framework import validity
|
||||
|
||||
class ContextInterface(object):
|
||||
"""Class for providing the interface for the Context object"""
|
||||
@@ -47,6 +35,23 @@ class ContextInterface(object):
|
||||
Returns a fully constructed object
|
||||
"""
|
||||
|
||||
class ObjectInterface(validity.ValidityRoutines):
|
||||
""" A base object required to be the ancestor of every object used in volatility """
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size, **kwargs):
|
||||
# Since objects are likely to be instantiated often,
|
||||
# we're only checking that a context is a context
|
||||
# Everything else may be wrong, but that will get caught later on
|
||||
self.type_check(context, ContextInterface)
|
||||
self._context = context
|
||||
self._offset = offset
|
||||
self._layer_name = layer_name
|
||||
self._symbol_name = symbol_name
|
||||
self._size = size
|
||||
|
||||
def cast(self, new_symbol_name):
|
||||
object_template = self._context.resolve(new_symbol_name)
|
||||
return object_template(context = self._context, layer_name = self._layer_name, offset = self._offset)
|
||||
|
||||
class Template(object):
|
||||
"""Class for all Factories that take offsets, and data layers and produce objects
|
||||
|
||||
@@ -76,72 +81,3 @@ class Template(object):
|
||||
|
||||
Returns: an object adhereing to the Object interface
|
||||
"""
|
||||
|
||||
class SymbolTableInterface(object):
|
||||
"""Handles a table of symbols"""
|
||||
|
||||
def __init__(self, name, native_symbols = None, *args, **kwargs):
|
||||
super(SymbolTableInterface, self).__init__(*args, **kwargs)
|
||||
if not isinstance(name, str) or not name:
|
||||
raise TypeError("Symbol Table name must be a string")
|
||||
if not isinstance(native_symbols, NativeTableInterface):
|
||||
raise TypeError("Symbol Table native_symbols must be a NativeTable, not " + str(type(native_symbols)))
|
||||
self.name = name
|
||||
self._native_symbols = native_symbols
|
||||
|
||||
### Required Symbol List functions
|
||||
|
||||
def resolve(self, symbol):
|
||||
"""Resolves a symbol name into an object template
|
||||
|
||||
If the symbol isn't found it raises a SymbolNotFound exception
|
||||
"""
|
||||
|
||||
@property
|
||||
def symbols(self):
|
||||
"""Returns an iterator of the symbol names"""
|
||||
|
||||
### Native Type Handler
|
||||
|
||||
@property
|
||||
def natives(self):
|
||||
"""Returns None or a symbol_space for handling space specific native types"""
|
||||
return self._native_symbols
|
||||
|
||||
### Functions for overriding classes
|
||||
|
||||
def set_symbol_class(self, symbol, clazz):
|
||||
"""Overrides the object class for a specific symbol
|
||||
|
||||
Symbol *must* be present in self.symbols
|
||||
"""
|
||||
|
||||
def get_symbol_class(self, symbol):
|
||||
"""Returns the class associated with a symbol"""
|
||||
|
||||
def del_symbol_class(self, symbol):
|
||||
"""Removes the associated class override for a specific symbol"""
|
||||
|
||||
### Helper functions that can be overridden
|
||||
|
||||
def __len__(self):
|
||||
"""Returns the number of items in the symbol list"""
|
||||
return len(self.symbols)
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Resolves a symbol name into an object template
|
||||
|
||||
Note, this method cannot sub-resolve throughout a whole symbol space
|
||||
"""
|
||||
return self.resolve(key)
|
||||
|
||||
def __iter__(self):
|
||||
"""Returns an iterator of the available keys"""
|
||||
return self.symbols
|
||||
|
||||
def __contains__(self, symbol):
|
||||
"""Determines whether a symbol exists in the list or not"""
|
||||
return symbol in self.symbols
|
||||
|
||||
class NativeTableInterface(SymbolTableInterface):
|
||||
"""Class to distinguish NativeSymbolLists from other symbol lists"""
|
||||
@@ -0,0 +1,52 @@
|
||||
'''
|
||||
Created on 4 May 2013
|
||||
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
from volatility.framework import validity, interfaces
|
||||
|
||||
class DataLayerInterface(validity.ValidityRoutines):
|
||||
"""A Layer that directly holds data (and does not translate it"""
|
||||
|
||||
def __init__(self, context, name):
|
||||
self._name = self.type_check(name, str)
|
||||
self._context = self.type_check(context, interfaces.ContextInterface)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Returns the layer name"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def maximum_address(self):
|
||||
"""Returns the maximum valid address of the space"""
|
||||
|
||||
@property
|
||||
def minimum_address(self):
|
||||
"""Returns the minimum valid address of the space"""
|
||||
|
||||
def is_valid(self, offset):
|
||||
"""Returns a boolean based on whether the offset is valid or not"""
|
||||
|
||||
def read(self, offset, length, pad = False):
|
||||
"""Read takes an offset and a size and returns a bytestring of length size
|
||||
|
||||
If there is a fault of any kind (such as a pagefault), an exception will be thrown
|
||||
unless pad is set, in which case the read errors will be replaced by null characters.
|
||||
"""
|
||||
|
||||
def write(self, offset, data):
|
||||
"""Writes a chunk of data at offset.
|
||||
|
||||
Any unavailable sections in the underlying bases will cause an exception to be thrown.
|
||||
Note: Writes are not atomic, therefore some data can be written, even if an exception is thrown.
|
||||
"""
|
||||
|
||||
class TranslationLayerInterface(DataLayerInterface):
|
||||
|
||||
def translate(self, offset):
|
||||
"""Returns a tuple of (offset, layer) indicating the translation of input domain to the output range"""
|
||||
|
||||
def mapping(self, offset, length):
|
||||
"""Returns a list of (offset, length, layer) mappings"""
|
||||
@@ -0,0 +1,72 @@
|
||||
'''
|
||||
Created on 4 May 2013
|
||||
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
from volatility.framework import validity
|
||||
|
||||
class SymbolTableInterface(validity.ValidityRoutines):
|
||||
"""Handles a table of symbols"""
|
||||
|
||||
def __init__(self, name, native_symbols = None, *args, **kwargs):
|
||||
super(SymbolTableInterface, self).__init__(*args, **kwargs)
|
||||
self.name = self.type_check(name or None, str)
|
||||
self._native_symbols = self.type_check(native_symbols, NativeTableInterface)
|
||||
|
||||
### Required Symbol List functions
|
||||
|
||||
def resolve(self, symbol):
|
||||
"""Resolves a symbol name into an object template
|
||||
|
||||
If the symbol isn't found it raises a SymbolNotFound exception
|
||||
"""
|
||||
|
||||
@property
|
||||
def symbols(self):
|
||||
"""Returns an iterator of the symbol names"""
|
||||
|
||||
### Native Type Handler
|
||||
|
||||
@property
|
||||
def natives(self):
|
||||
"""Returns None or a symbol_space for handling space specific native types"""
|
||||
return self._native_symbols
|
||||
|
||||
### Functions for overriding classes
|
||||
|
||||
def set_symbol_class(self, symbol, clazz):
|
||||
"""Overrides the object class for a specific symbol
|
||||
|
||||
Symbol *must* be present in self.symbols
|
||||
"""
|
||||
|
||||
def get_symbol_class(self, symbol):
|
||||
"""Returns the class associated with a symbol"""
|
||||
|
||||
def del_symbol_class(self, symbol):
|
||||
"""Removes the associated class override for a specific symbol"""
|
||||
|
||||
### Helper functions that can be overridden
|
||||
|
||||
def __len__(self):
|
||||
"""Returns the number of items in the symbol list"""
|
||||
return len(self.symbols)
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Resolves a symbol name into an object template
|
||||
|
||||
Note, this method cannot sub-resolve throughout a whole symbol space
|
||||
"""
|
||||
return self.resolve(key)
|
||||
|
||||
def __iter__(self):
|
||||
"""Returns an iterator of the available keys"""
|
||||
return self.symbols
|
||||
|
||||
def __contains__(self, symbol):
|
||||
"""Determines whether a symbol exists in the list or not"""
|
||||
return symbol in self.symbols
|
||||
|
||||
class NativeTableInterface(SymbolTableInterface):
|
||||
"""Class to distinguish NativeSymbolLists from other symbol lists"""
|
||||
@@ -0,0 +1,35 @@
|
||||
'''
|
||||
Created on 4 May 2013
|
||||
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
from volatility.framework.interfaces import layers
|
||||
|
||||
class BufferDataLayer(layers.DataLayerInterface):
|
||||
"""A DataLayer class backed by a buffer in memory, designed for testing and swift data access"""
|
||||
|
||||
def __init__(self, name = None, buffer = None):
|
||||
super(BufferDataLayer, self).__init__(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):]
|
||||
@@ -6,8 +6,8 @@ Created on 17 Feb 2013
|
||||
|
||||
import struct
|
||||
import collections
|
||||
import volatility.framework.interfaces as interfaces
|
||||
import volatility.framework.templates as templates
|
||||
from volatility.framework import interfaces
|
||||
from volatility.framework.obj import templates
|
||||
|
||||
class Void(interfaces.ObjectInterface):
|
||||
"""Returns an object to represent void/unknown types"""
|
||||
@@ -4,7 +4,7 @@ Created on 1 Mar 2013
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
import volatility.framework.interfaces as interfaces
|
||||
from volatility.framework import interfaces
|
||||
|
||||
class ObjectTemplate(interfaces.Template):
|
||||
"""Factory class that produces objects that adhere to the Object interface on demand
|
||||
@@ -5,9 +5,7 @@ Created on 7 Feb 2013
|
||||
'''
|
||||
|
||||
import collections
|
||||
from volatility.framework import obj, templates, interfaces
|
||||
from volatility.framework.exceptions import SymbolNotFoundException
|
||||
import volatility.framework.exceptions as exceptions
|
||||
from volatility.framework import obj, interfaces, exceptions
|
||||
|
||||
class SymbolSpace(collections.Mapping):
|
||||
"""Handles an ordered collection of SymbolTables
|
||||
@@ -17,7 +15,7 @@ class SymbolSpace(collections.Mapping):
|
||||
"""
|
||||
|
||||
def __init__(self, native_symbols):
|
||||
if not isinstance(native_symbols, interfaces.NativeTableInterface):
|
||||
if not isinstance(native_symbols, interfaces.symbols.NativeTableInterface):
|
||||
raise TypeError("SymbolSpace native_symbols must be NativeSymbolInterface")
|
||||
self._dict = collections.OrderedDict()
|
||||
self._native_symbols = native_symbols
|
||||
@@ -38,7 +36,7 @@ class SymbolSpace(collections.Mapping):
|
||||
|
||||
def append(self, value):
|
||||
"""Adds a symbol_list to the end of the space"""
|
||||
if not isinstance(value, interfaces.SymbolTableInterface):
|
||||
if not isinstance(value, interfaces.symbols.SymbolTableInterface):
|
||||
raise TypeError(value)
|
||||
if value.name in self._dict:
|
||||
del self._dict[value.name]
|
||||
@@ -76,7 +74,7 @@ class SymbolSpace(collections.Mapping):
|
||||
while template_traverse_list:
|
||||
traverser, template_traverse_list = template_traverse_list[0], template_traverse_list[1:]
|
||||
for child in traverser.children:
|
||||
if isinstance(child, templates.ReferenceTemplate):
|
||||
if isinstance(child, obj.templates.ReferenceTemplate):
|
||||
# If we haven't seen it before, subresolve it and also add it
|
||||
# to the "symbols that still need traversing" list
|
||||
if child.symbol_name not in resolved:
|
||||
|
||||
@@ -5,11 +5,9 @@ Created on 10 Apr 2013
|
||||
'''
|
||||
import copy
|
||||
import struct
|
||||
import volatility.framework.obj as obj
|
||||
import volatility.framework.templates as templates
|
||||
import volatility.framework.interfaces as interfaces
|
||||
from volatility.framework import obj, interfaces
|
||||
|
||||
class NativeTable(interfaces.NativeTableInterface):
|
||||
class NativeTable(interfaces.symbols.NativeTableInterface):
|
||||
"""Symbol List that handles Native types"""
|
||||
|
||||
def __init__(self, name, native_dictionary):
|
||||
@@ -35,19 +33,19 @@ class NativeTable(interfaces.NativeTableInterface):
|
||||
symbol_space is used to resolve any target symbols if they don't exist in this list
|
||||
"""
|
||||
if symbol_name == 'void':
|
||||
return templates.ObjectTemplate(obj.Void, symbol_name = symbol_name, size = 0)
|
||||
return obj.templates.ObjectTemplate(obj.Void, symbol_name = symbol_name, size = 0)
|
||||
elif symbol_name == 'array':
|
||||
return templates.ObjectTemplate(obj.Array, symbol_name = symbol_name, count = 0, target = self.resolve('void'), size = 0)
|
||||
return obj.templates.ObjectTemplate(obj.Array, symbol_name = symbol_name, count = 0, target = self.resolve('void'), size = 0)
|
||||
elif symbol_name == 'Enumeration':
|
||||
return templates.ObjectTemplate(obj.Enumeration, symbol_name = symbol_name, target = self.resolve('void'), choices = {}, size = 0)
|
||||
return obj.templates.ObjectTemplate(obj.Enumeration, symbol_name = symbol_name, target = self.resolve('void'), choices = {}, size = 0)
|
||||
elif symbol_name == 'BitField':
|
||||
return templates.ObjectTemplate(obj.BitField, symbol_name = symbol_name, start_bit = 0, end_bit = 0, size = 0)
|
||||
return obj.templates.ObjectTemplate(obj.BitField, symbol_name = symbol_name, start_bit = 0, end_bit = 0, size = 0)
|
||||
|
||||
_native_type, native_format = self._native_dictionary[symbol_name]
|
||||
native_size = struct.calcsize(native_format)
|
||||
if symbol_name == 'pointer':
|
||||
return templates.ObjectTemplate(obj.Pointer, symbol_name = symbol_name, target = self.resolve('void'), size = native_size)
|
||||
return templates.ObjectTemplate(self.get_symbol_class(symbol_name), symbol_name = symbol_name, struct_format = native_format, size = native_size)
|
||||
return obj.templates.ObjectTemplate(obj.Pointer, symbol_name = symbol_name, target = self.resolve('void'), size = native_size)
|
||||
return obj.templates.ObjectTemplate(self.get_symbol_class(symbol_name), symbol_name = symbol_name, struct_format = native_format, size = native_size)
|
||||
|
||||
native_types = {'int' : (obj.Integer, '<i'),
|
||||
'long': (obj.Integer, '<i'),
|
||||
|
||||
@@ -5,10 +5,8 @@ Created on 10 Apr 2013
|
||||
'''
|
||||
|
||||
import copy
|
||||
import volatility.framework.exceptions as exceptions
|
||||
import volatility.framework.interfaces as interfaces
|
||||
import volatility.framework.templates as templates
|
||||
import volatility.framework.obj as obj
|
||||
from volatility.framework import exceptions, obj
|
||||
from volatility.framework.interfaces import symbols
|
||||
|
||||
### TODO
|
||||
#
|
||||
@@ -36,7 +34,7 @@ import volatility.framework.obj as obj
|
||||
# Need to figure out how to tell the difference for vtypes between
|
||||
# vtype list and a struct dictionary
|
||||
|
||||
class VTypeSymbolTable(interfaces.SymbolTableInterface):
|
||||
class VTypeSymbolTable(symbols.SymbolTableInterface):
|
||||
"""Symbol Table that handles vtype datastructures"""
|
||||
|
||||
def __init__(self, name, vtype_dictionary, native_symbols = None):
|
||||
@@ -87,7 +85,7 @@ class VTypeSymbolTable(interfaces.SymbolTableInterface):
|
||||
if len(dictionary) > 1:
|
||||
raise exceptions.SymbolSpaceError("Unknown vtype format: " + repr(dictionary))
|
||||
|
||||
return templates.ReferenceTemplate(symbol_name = self.name + "!" + symbol_name)
|
||||
return obj.templates.ReferenceTemplate(symbol_name = self.name + "!" + symbol_name)
|
||||
|
||||
@property
|
||||
def symbols(self):
|
||||
@@ -105,4 +103,4 @@ class VTypeSymbolTable(interfaces.SymbolTableInterface):
|
||||
member = (relative_offset, self._vtypedict_to_template(vtypedict))
|
||||
members[member_name] = member
|
||||
object_class = self.get_symbol_class(symbol_name)
|
||||
return templates.ObjectTemplate(object_class = object_class, symbol_name = symbol_name, size = size, members = members)
|
||||
return obj.templates.ObjectTemplate(object_class = object_class, symbol_name = symbol_name, size = size, members = members)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
'''
|
||||
Created on 4 May 2013
|
||||
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
class ValidityRoutines(object):
|
||||
"""Class to hold all validation routines, such as type checking"""
|
||||
|
||||
def type_check(self, value, valid_type):
|
||||
"""Checks that value is an instance of valid_type, and returns value if it is, or throws a TypeError otherwise"""
|
||||
if not isinstance(value, valid_type):
|
||||
raise TypeError(self.__class__.__name__ + " expected " + valid_type.__class__.__name__ + ", not " + type(value))
|
||||
return value
|
||||
|
||||
def confirm(self, assertion, error):
|
||||
"""Acts like an assertion, but will not be disabled when __debug__ is disabled"""
|
||||
if not assertion:
|
||||
if error is None:
|
||||
error = "An unspecified Assertion was not met"
|
||||
raise AssertionError(error)
|
||||
Reference in New Issue
Block a user