Restructure the packages, change importing style to from ... import.

This commit is contained in:
Mike Auty
2013-05-04 15:44:59 +01:00
parent e654391e86
commit dc65c356fc
11 changed files with 219 additions and 109 deletions
+1 -1
View File
@@ -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"""
+52
View File
@@ -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"""
+35
View File
@@ -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
+4 -6
View File
@@ -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:
+8 -10
View File
@@ -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 -7
View File
@@ -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)
+21
View File
@@ -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)