mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-17 20:35:40 +02:00
Refactor code locations, tidy up object initializers and add in File Layer.
This commit is contained in:
+10
-2
@@ -42,10 +42,18 @@ def test_memory():
|
||||
ctx = framework.Context(nativelst)
|
||||
ctx.symbol_space.append(ntkrnlmp)
|
||||
|
||||
base = layers.BufferDataLayer(ctx, 'data', buffer = b"\x04\x00\x00\x00\x01\x00\x00\x00\x02\x00")
|
||||
base = layers.physical.BufferDataLayer(ctx, 'data', buffer = b"\x04\x00\x00\x00\x01\x02\x03\x04\x02\x00")
|
||||
ctx.memory.add_layer(base)
|
||||
val = ctx.object('ntkrnlmp!TEST_POINTER', 'data', 0)
|
||||
print(hex(val.point1.test1), val.point1.test1.size)
|
||||
print(hex(val.point1.test1), val.point1.test2)
|
||||
|
||||
# TODO:
|
||||
#
|
||||
# Plugins - Tree/List input/output
|
||||
# Architectures
|
||||
# Scanning Framework
|
||||
# GUI/UI
|
||||
#
|
||||
|
||||
if __name__ == '__main__':
|
||||
# import timeit
|
||||
|
||||
@@ -30,7 +30,7 @@ def require_version(*args):
|
||||
|
||||
from volatility.framework import interfaces, symbols, layers
|
||||
|
||||
class Context(interfaces.ContextInterface):
|
||||
class Context(interfaces.context.ContextInterface):
|
||||
"""Maintains the context within which to construct objects"""
|
||||
|
||||
def __init__(self, natives):
|
||||
|
||||
@@ -4,85 +4,7 @@ Created on 12 Apr 2013
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
import copy
|
||||
from volatility.framework import validity
|
||||
|
||||
class ContextInterface(object):
|
||||
"""Class for providing the interface for the Context object"""
|
||||
|
||||
def __init__(self):
|
||||
"""Intializes the context with a symbol_space"""
|
||||
|
||||
### Symbol Space Functions
|
||||
|
||||
@property
|
||||
def symbol_space(self):
|
||||
"""Returns the symbol_space for the context"""
|
||||
|
||||
### Memory Functions
|
||||
|
||||
@property
|
||||
def memory(self):
|
||||
"""Returns the memory object for the context"""
|
||||
|
||||
def add_layer(self, layer):
|
||||
"""Adds a named translation layer to the context memory"""
|
||||
self.memory.add_layer(layer)
|
||||
|
||||
### Object Factory Functions
|
||||
|
||||
def object(self, symbol, layer_name, offset):
|
||||
"""Object factory, takes a context, symbol, offset and optional layername
|
||||
|
||||
Looks up the layername in the context, finds the object template based on the symbol,
|
||||
and constructs an object using the object template on the layer at the offset.
|
||||
|
||||
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, parent = None, **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._context = self.type_check(context, ContextInterface)
|
||||
self._parent = None if not parent else self.type_check(parent, ObjectInterface)
|
||||
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.symbol_space.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
|
||||
|
||||
This is effectively a class for currying object calls
|
||||
"""
|
||||
def __init__(self, symbol_name = None, **kwargs):
|
||||
"""Stores the keyword arguments for later use"""
|
||||
self._kwargs = kwargs
|
||||
self._symbol_name = symbol_name
|
||||
|
||||
@property
|
||||
def symbol_name(self):
|
||||
"""Returns the name of the particular symbol"""
|
||||
return self._symbol_name
|
||||
|
||||
@property
|
||||
def arguments(self):
|
||||
"""Returns the keyword arguments stored earlier"""
|
||||
return copy.deepcopy(self._kwargs)
|
||||
|
||||
def update_arguments(self, **newargs):
|
||||
"""Updates the keyword arguments"""
|
||||
self._kwargs.update(newargs)
|
||||
|
||||
def __call__(self, context, layer_name, offset, parent = None):
|
||||
"""Constructs the object
|
||||
|
||||
Returns: an object adhereing to the Object interface
|
||||
"""
|
||||
# Import the submodules we want people to be able to use without importing them themselves
|
||||
# This will also avoid namespace issues, because people can use interfaces.layers to
|
||||
# avoid clashing with the layers package
|
||||
from volatility.framework.interfaces import layers, symbols, context, objects
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
'''
|
||||
Created on 6 May 2013
|
||||
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
class ContextInterface(object):
|
||||
"""Class for providing the interface for the Context object"""
|
||||
|
||||
def __init__(self):
|
||||
"""Intializes the context with a symbol_space"""
|
||||
|
||||
### Symbol Space Functions
|
||||
|
||||
@property
|
||||
def symbol_space(self):
|
||||
"""Returns the symbol_space for the context"""
|
||||
|
||||
### Memory Functions
|
||||
|
||||
@property
|
||||
def memory(self):
|
||||
"""Returns the memory object for the context"""
|
||||
|
||||
def add_layer(self, layer):
|
||||
"""Adds a named translation layer to the context memory"""
|
||||
self.memory.add_layer(layer)
|
||||
|
||||
### Object Factory Functions
|
||||
|
||||
def object(self, symbol, layer_name, offset):
|
||||
"""Object factory, takes a context, symbol, offset and optional layername
|
||||
|
||||
Looks up the layername in the context, finds the object template based on the symbol,
|
||||
and constructs an object using the object template on the layer at the offset.
|
||||
|
||||
Returns a fully constructed object
|
||||
"""
|
||||
|
||||
@@ -4,14 +4,16 @@ Created on 4 May 2013
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
from volatility.framework import validity, interfaces
|
||||
from volatility.framework import validity
|
||||
# We can't just import interfaces because we'd have a cycle going
|
||||
from volatility.framework.interfaces import context as context_module
|
||||
|
||||
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)
|
||||
self._context = self.type_check(context, context_module.ContextInterface)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@@ -30,7 +32,7 @@ class DataLayerInterface(validity.ValidityRoutines):
|
||||
"""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
|
||||
"""Read takes an offset and a size and returns 'bytes' (not 'str') 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.
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
'''
|
||||
Created on 6 May 2013
|
||||
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
import copy
|
||||
from volatility.framework import validity
|
||||
from volatility.framework.interfaces import context as context_module
|
||||
|
||||
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, parent = None):
|
||||
# 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._context = self.type_check(context, context_module.ContextInterface)
|
||||
self._parent = None if not parent else self.type_check(parent, ObjectInterface)
|
||||
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.symbol_space.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
|
||||
|
||||
This is effectively a class for currying object calls
|
||||
"""
|
||||
def __init__(self, symbol_name = None, **kwargs):
|
||||
"""Stores the keyword arguments for later use"""
|
||||
self._kwargs = kwargs
|
||||
self._symbol_name = symbol_name
|
||||
|
||||
@property
|
||||
def symbol_name(self):
|
||||
"""Returns the name of the particular symbol"""
|
||||
return self._symbol_name
|
||||
|
||||
@property
|
||||
def arguments(self):
|
||||
"""Returns the keyword arguments stored earlier"""
|
||||
return copy.deepcopy(self._kwargs)
|
||||
|
||||
def update_arguments(self, **newargs):
|
||||
"""Updates the keyword arguments"""
|
||||
self._kwargs.update(newargs)
|
||||
|
||||
def __call__(self, context, layer_name, offset, parent = None):
|
||||
"""Constructs the object
|
||||
|
||||
Returns: an object adhereing to the Object interface
|
||||
"""
|
||||
@@ -9,8 +9,7 @@ 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)
|
||||
def __init__(self, name, native_symbols = None):
|
||||
self.name = self.type_check(name or None, str)
|
||||
self._native_symbols = self.type_check(native_symbols, NativeTableInterface)
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ Created on 4 May 2013
|
||||
@author: mike
|
||||
'''
|
||||
|
||||
from volatility.framework import validity, exceptions
|
||||
from volatility.framework.interfaces import layers
|
||||
from volatility.framework import validity, interfaces, exceptions
|
||||
from volatility.framework.layers import physical
|
||||
|
||||
class Memory(validity.ValidityRoutines):
|
||||
"""Container for multiple layers of data"""
|
||||
@@ -14,7 +14,10 @@ class Memory(validity.ValidityRoutines):
|
||||
self._layers = {}
|
||||
|
||||
def read(self, layer, offset, length, pad = False):
|
||||
"""Reads from a particular layer at offset for length bytes"""
|
||||
"""Reads from a particular layer at offset for length bytes
|
||||
|
||||
Returns 'bytes' not 'str'
|
||||
"""
|
||||
return self[layer].read(offset, length, pad)
|
||||
|
||||
def write(self, layer, offset, data):
|
||||
@@ -26,8 +29,8 @@ class Memory(validity.ValidityRoutines):
|
||||
|
||||
This will throw an exception if the required dependencies are not met
|
||||
"""
|
||||
self.type_check(layer, layers.DataLayerInterface)
|
||||
if isinstance(layer, layers.TranslationLayerInterface):
|
||||
self.type_check(layer, interfaces.layers.DataLayerInterface)
|
||||
if isinstance(layer, interfaces.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]
|
||||
@@ -52,31 +55,4 @@ class Memory(validity.ValidityRoutines):
|
||||
|
||||
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):]
|
||||
# TODO: Is having a cycle check necessary?
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
'''
|
||||
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):
|
||||
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):
|
||||
"""Returns the smallest available address in the space"""
|
||||
return 0
|
||||
|
||||
def is_valid(self, offset):
|
||||
"""Returns whether the offset is valid or not"""
|
||||
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):]
|
||||
|
||||
class FileLayer(interfaces.layers.DataLayerInterface):
|
||||
"""a DataLayer backed by a file on the filesystem"""
|
||||
|
||||
def __init__(self, context, name, filename):
|
||||
super(FileLayer, self).__init__(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 (offset >= self.minimum_address and 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):
|
||||
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"""
|
||||
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)
|
||||
@@ -7,9 +7,9 @@ Created on 17 Feb 2013
|
||||
import struct
|
||||
import collections
|
||||
from volatility.framework import interfaces
|
||||
from volatility.framework.obj import templates
|
||||
from volatility.framework.objects import templates
|
||||
|
||||
class Void(interfaces.ObjectInterface):
|
||||
class Void(interfaces.objects.ObjectInterface):
|
||||
"""Returns an object to represent void/unknown types"""
|
||||
@classmethod
|
||||
def template_size(cls, arguments):
|
||||
@@ -25,10 +25,10 @@ class Void(interfaces.ObjectInterface):
|
||||
def template_replace_child(cls, old_child, new_child, arguments):
|
||||
"""Dummy method that does nothing for Void objects"""
|
||||
|
||||
class PrimitiveObject(interfaces.ObjectInterface):
|
||||
class PrimitiveObject(interfaces.objects.ObjectInterface):
|
||||
"""PrimitiveObject is an interface for any objects that should simulate a Python primitive"""
|
||||
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, parent = None, struct_format = '<I', **kwargs):
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, parent = None, struct_format = '<I'):
|
||||
super(PrimitiveObject, self).__init__(context = context,
|
||||
layer_name = layer_name,
|
||||
offset = offset,
|
||||
@@ -87,7 +87,7 @@ class String(PrimitiveObject, str):
|
||||
|
||||
class Pointer(Integer):
|
||||
"""Pointer which points to another object"""
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, parent = None, struct_format = None, target = None, **kwargs):
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, parent = None, struct_format = None, target = None):
|
||||
if not isinstance(target, templates.ObjectTemplate):
|
||||
raise TypeError("Pointer targets must be an ObjectTemplate")
|
||||
super(Pointer, self).__init__(context,
|
||||
@@ -145,16 +145,16 @@ class BitField(PrimitiveObject, int):
|
||||
return [arguments['target']]
|
||||
return []
|
||||
|
||||
class Enumeration(interfaces.ObjectInterface):
|
||||
class Enumeration(interfaces.objects.ObjectInterface):
|
||||
"""Returns an object made up of choices"""
|
||||
# FIXME: Add in body for the enumeration object
|
||||
@classmethod
|
||||
def template_children(cls, arguments):
|
||||
return []
|
||||
|
||||
class Array(interfaces.ObjectInterface, collections.Sequence):
|
||||
class Array(interfaces.objects.ObjectInterface, collections.Sequence):
|
||||
"""Object which can contain a fixed number of an object type"""
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, parent = None, count = 0, target = None, **kwargs):
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, parent = None, count = 0, target = None):
|
||||
if not isinstance(target, templates.ObjectTemplate):
|
||||
raise TypeError("Array target must be an ObjectTemplate")
|
||||
super(Array, self).__init__(context = context,
|
||||
@@ -195,10 +195,10 @@ class Array(interfaces.ObjectInterface, collections.Sequence):
|
||||
"""Returns the length of the array"""
|
||||
return self._count
|
||||
|
||||
class Struct(interfaces.ObjectInterface):
|
||||
class Struct(interfaces.objects.ObjectInterface):
|
||||
"""Object which can contain members that are other objects"""
|
||||
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, members = None, parent = None, **kwargs):
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, members = None, parent = None):
|
||||
super(Struct, self).__init__(context = context,
|
||||
layer_name = layer_name,
|
||||
offset = offset,
|
||||
@@ -6,7 +6,7 @@ Created on 1 Mar 2013
|
||||
|
||||
from volatility.framework import interfaces, validity
|
||||
|
||||
class ObjectTemplate(interfaces.Template, validity.ValidityRoutines):
|
||||
class ObjectTemplate(interfaces.objects.Template, validity.ValidityRoutines):
|
||||
"""Factory class that produces objects that adhere to the Object interface on demand
|
||||
|
||||
This is effectively a method of currying, but adds more structure to avoid abuse.
|
||||
@@ -17,7 +17,7 @@ class ObjectTemplate(interfaces.Template, validity.ValidityRoutines):
|
||||
"""
|
||||
def __init__(self, object_class = None, symbol_name = None, **kwargs):
|
||||
super(ObjectTemplate, self).__init__(symbol_name = symbol_name, **kwargs)
|
||||
self.object_class = self.class_check(object_class, interfaces.ObjectInterface)
|
||||
self.object_class = self.class_check(object_class, interfaces.objects.ObjectInterface)
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
@@ -50,7 +50,7 @@ class ObjectTemplate(interfaces.Template, validity.ValidityRoutines):
|
||||
self._kwargs['symbol_name'] = self.symbol_name
|
||||
return self.object_class(context = context, layer_name = layer_name, offset = offset, parent = parent, **self._kwargs)
|
||||
|
||||
class ReferenceTemplate(interfaces.Template):
|
||||
class ReferenceTemplate(interfaces.objects.Template):
|
||||
"""Factory class that produces objects based on a delayed reference type
|
||||
|
||||
It should not return any attributes
|
||||
@@ -5,7 +5,7 @@ Created on 7 Feb 2013
|
||||
'''
|
||||
|
||||
import collections
|
||||
from volatility.framework import obj, interfaces, exceptions
|
||||
from volatility.framework import objects, interfaces, exceptions
|
||||
|
||||
class SymbolSpace(collections.Mapping):
|
||||
"""Handles an ordered collection of SymbolTables
|
||||
@@ -76,7 +76,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, obj.templates.ReferenceTemplate):
|
||||
if isinstance(child, objects.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:
|
||||
|
||||
@@ -4,8 +4,7 @@ Created on 10 Apr 2013
|
||||
@author: mike
|
||||
'''
|
||||
import copy
|
||||
import struct
|
||||
from volatility.framework import obj, interfaces
|
||||
from volatility.framework import objects, interfaces
|
||||
|
||||
class NativeTable(interfaces.symbols.NativeTableInterface):
|
||||
"""Symbol List that handles Native types"""
|
||||
@@ -19,7 +18,7 @@ class NativeTable(interfaces.symbols.NativeTableInterface):
|
||||
self._overrides[native_type] = native_class
|
||||
|
||||
def get_symbol_class(self, symbol):
|
||||
ntype, fmt = native_types.get(symbol, (obj.Integer, ''))
|
||||
ntype, fmt = native_types.get(symbol, (objects.Integer, ''))
|
||||
return ntype
|
||||
|
||||
@property
|
||||
@@ -27,45 +26,45 @@ class NativeTable(interfaces.symbols.NativeTableInterface):
|
||||
"""Returns an iterator of the symbol names"""
|
||||
return set(self._native_dictionary.keys()).union(set(['Enumeration', 'array', 'BitField', 'void', 'pointer']))
|
||||
|
||||
def resolve(self, symbol_name, **kwargs):
|
||||
def resolve(self, symbol_name):
|
||||
"""Resolves a symbol name into an object template
|
||||
|
||||
symbol_space is used to resolve any target symbols if they don't exist in this list
|
||||
"""
|
||||
additional = {}
|
||||
if symbol_name == 'void':
|
||||
return obj.templates.ObjectTemplate(obj.Void, symbol_name = symbol_name)
|
||||
return objects.templates.ObjectTemplate(objects.Void, symbol_name = symbol_name)
|
||||
elif symbol_name == 'array':
|
||||
return obj.templates.ObjectTemplate(obj.Array, symbol_name = symbol_name, count = 0, target = self.resolve('void'))
|
||||
return objects.templates.ObjectTemplate(objects.Array, symbol_name = symbol_name, count = 0, target = self.resolve('void'))
|
||||
elif symbol_name == 'Enumeration':
|
||||
return obj.templates.ObjectTemplate(obj.Enumeration, symbol_name = symbol_name, target = self.resolve('void'), choices = {})
|
||||
return objects.templates.ObjectTemplate(objects.Enumeration, symbol_name = symbol_name, target = self.resolve('void'), choices = {})
|
||||
elif symbol_name == 'BitField':
|
||||
return obj.templates.ObjectTemplate(obj.BitField, symbol_name = symbol_name, start_bit = 0, end_bit = 0)
|
||||
return objects.templates.ObjectTemplate(objects.BitField, symbol_name = symbol_name, start_bit = 0, end_bit = 0)
|
||||
|
||||
_native_type, native_format = self._native_dictionary[symbol_name]
|
||||
if symbol_name == 'pointer':
|
||||
additional = {'target': self.resolve('void')}
|
||||
return obj.templates.ObjectTemplate(self.get_symbol_class(symbol_name), #pylint: disable-msg=W0142
|
||||
return objects.templates.ObjectTemplate(self.get_symbol_class(symbol_name), #pylint: disable-msg=W0142
|
||||
symbol_name = symbol_name,
|
||||
struct_format = native_format,
|
||||
**additional)
|
||||
|
||||
native_types = {'int' : (obj.Integer, '<i'),
|
||||
'long': (obj.Integer, '<i'),
|
||||
'unsigned long' : (obj.Integer, '<I'),
|
||||
'unsigned int' : (obj.Integer, '<I'),
|
||||
'pointer' : (obj.Pointer, '<I'),
|
||||
'char' : (obj.Integer, '<b'),
|
||||
'byte' : (obj.Bytes, '<c'),
|
||||
'unsigned char' : (obj.Integer, '<B'),
|
||||
'unsigned short int' : (obj.Integer, '<H'),
|
||||
'unsigned short' : (obj.Integer, '<H'),
|
||||
'unsigned be short' : (obj.Integer, '>H'),
|
||||
'short' : (obj.Integer, '<h'),
|
||||
'long long' : (obj.Integer, '<q'),
|
||||
'unsigned long long' : (obj.Integer, '<Q'),
|
||||
'float': (obj.Float, "<d"),
|
||||
'double': (obj.Float, "<d")}
|
||||
native_types = {'int' : (objects.Integer, '<i'),
|
||||
'long': (objects.Integer, '<i'),
|
||||
'unsigned long' : (objects.Integer, '<I'),
|
||||
'unsigned int' : (objects.Integer, '<I'),
|
||||
'pointer' : (objects.Pointer, '<I'),
|
||||
'char' : (objects.Integer, '<b'),
|
||||
'byte' : (objects.Bytes, '<c'),
|
||||
'unsigned char' : (objects.Integer, '<B'),
|
||||
'unsigned short int' : (objects.Integer, '<H'),
|
||||
'unsigned short' : (objects.Integer, '<H'),
|
||||
'unsigned be short' : (objects.Integer, '>H'),
|
||||
'short' : (objects.Integer, '<h'),
|
||||
'long long' : (objects.Integer, '<q'),
|
||||
'unsigned long long' : (objects.Integer, '<Q'),
|
||||
'float': (objects.Float, "<d"),
|
||||
'double': (objects.Float, "<d")}
|
||||
x86NativeTable = NativeTable("native", native_types)
|
||||
native_types['pointer'] = (obj.Pointer, '<Q')
|
||||
native_types['pointer'] = (objects.Pointer, '<Q')
|
||||
x64NativeTable = NativeTable("native", native_types)
|
||||
|
||||
@@ -5,8 +5,7 @@ Created on 10 Apr 2013
|
||||
'''
|
||||
|
||||
import copy
|
||||
from volatility.framework import exceptions, obj
|
||||
from volatility.framework.interfaces import symbols
|
||||
from volatility.framework import exceptions, objects, interfaces
|
||||
|
||||
### TODO
|
||||
#
|
||||
@@ -34,7 +33,7 @@ from volatility.framework.interfaces import symbols
|
||||
# Need to figure out how to tell the difference for vtypes between
|
||||
# vtype list and a struct dictionary
|
||||
|
||||
class VTypeSymbolTable(symbols.SymbolTableInterface):
|
||||
class VTypeSymbolTable(interfaces.symbols.SymbolTableInterface):
|
||||
"""Symbol Table that handles vtype datastructures"""
|
||||
|
||||
def __init__(self, name, vtype_dictionary, native_symbols = None):
|
||||
@@ -43,7 +42,7 @@ class VTypeSymbolTable(symbols.SymbolTableInterface):
|
||||
self._overrides = {}
|
||||
|
||||
def get_symbol_class(self, symbol):
|
||||
return self._overrides.get(symbol, obj.Struct)
|
||||
return self._overrides.get(symbol, objects.Struct)
|
||||
|
||||
def set_symbol_class(self, symbol, clazz):
|
||||
if symbol not in self.symbols:
|
||||
@@ -85,7 +84,7 @@ class VTypeSymbolTable(symbols.SymbolTableInterface):
|
||||
if len(dictionary) > 1:
|
||||
raise exceptions.SymbolSpaceError("Unknown vtype format: " + repr(dictionary))
|
||||
|
||||
return obj.templates.ReferenceTemplate(symbol_name = self.name + "!" + symbol_name)
|
||||
return objects.templates.ReferenceTemplate(symbol_name = self.name + "!" + symbol_name)
|
||||
|
||||
@property
|
||||
def symbols(self):
|
||||
@@ -103,4 +102,4 @@ class VTypeSymbolTable(symbols.SymbolTableInterface):
|
||||
member = (relative_offset, self._vtypedict_to_template(vtypedict))
|
||||
members[member_name] = member
|
||||
object_class = self.get_symbol_class(symbol_name)
|
||||
return obj.templates.ObjectTemplate(object_class = object_class, symbol_name = symbol_name, size = size, members = members)
|
||||
return objects.templates.ObjectTemplate(object_class = object_class, symbol_name = symbol_name, size = size, members = members)
|
||||
|
||||
Reference in New Issue
Block a user