mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-10 11:47:38 +02:00
Reformat and optimize code, including trailing whitespace and end of file newline.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Volatility 3 - An open-source memory forensics framework"""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###
|
||||
# ##
|
||||
#
|
||||
# Libtool version scheme
|
||||
#
|
||||
@@ -11,13 +11,15 @@
|
||||
# 3. If only additions to the interface have been made, increment age
|
||||
# 4. If changes or removals of the interface have been made, set age to 0
|
||||
|
||||
_current = 3 # Number of releases of the library with any change
|
||||
_revision = 0 # Number of changes that don't affect the interface
|
||||
_age = 0 # Number of consecutive versions of the interface the current version supports
|
||||
CURRENT = 3 # Number of releases of the library with any change
|
||||
REVISION = 0 # Number of changes that don't affect the interface
|
||||
AGE = 0 # Number of consecutive versions of the interface the current version supports
|
||||
|
||||
|
||||
def version():
|
||||
"""Provides the so version number of the library"""
|
||||
return _current - _age, _age, _revision
|
||||
return CURRENT - AGE, AGE, REVISION
|
||||
|
||||
|
||||
def require_version(*args):
|
||||
"""Checks the required version of a plugin"""
|
||||
@@ -31,8 +33,10 @@ def require_version(*args):
|
||||
" is an older revision than the required version " +
|
||||
".".join([str(x) for x in args[0:2]]))
|
||||
|
||||
|
||||
from volatility.framework import interfaces, symbols, layers
|
||||
|
||||
|
||||
class Context(interfaces.context.ContextInterface):
|
||||
"""Maintains the context within which to construct objects
|
||||
|
||||
@@ -54,7 +58,7 @@ class Context(interfaces.context.ContextInterface):
|
||||
self._symbol_space = symbols.SymbolSpace(natives)
|
||||
self._memory = layers.Memory()
|
||||
|
||||
### Symbol Space Functions
|
||||
# ## Symbol Space Functions
|
||||
|
||||
@property
|
||||
def symbol_space(self):
|
||||
@@ -67,7 +71,7 @@ class Context(interfaces.context.ContextInterface):
|
||||
"""A Memory object, allowing access to all data and translation layers currently available within the context"""
|
||||
return self._memory
|
||||
|
||||
### Address Space Functions
|
||||
# ## Address Space Functions
|
||||
|
||||
def add_translation_layer(self, layer):
|
||||
"""Adds a named translation layer to the context
|
||||
@@ -78,14 +82,14 @@ class Context(interfaces.context.ContextInterface):
|
||||
"""
|
||||
self._memory.add_layer(layer)
|
||||
|
||||
### Object Factory Functions
|
||||
# ## 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.
|
||||
|
||||
|
||||
:return: A fully constructed object
|
||||
:rtype: :py:class:`volatility.framework.interfaces.objects.ObjectInterface`
|
||||
"""
|
||||
|
||||
@@ -6,8 +6,10 @@ Created on 7 May 2013
|
||||
|
||||
from volatility.framework import validity
|
||||
|
||||
|
||||
class Option(validity.ValidityRoutines):
|
||||
"""Class to handle a single specific configuration option"""
|
||||
|
||||
def __init__(self, name, option_type, definition = None, description = None):
|
||||
"""Creates a new option"""
|
||||
self.type_check(option_type, type)
|
||||
@@ -18,20 +20,24 @@ class Option(validity.ValidityRoutines):
|
||||
|
||||
@property
|
||||
def option_type(self):
|
||||
"""The data type of the Option, such as string, integer, etc"""
|
||||
return self._option_type
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""The name of the Option."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
"""A short description of what the Option is designed to affect or achieve."""
|
||||
return self._description
|
||||
|
||||
@property
|
||||
def definition(self):
|
||||
return self._definition
|
||||
|
||||
|
||||
class ConfigurationGroup(validity.ValidityRoutines):
|
||||
"""Class to handle configuration groups, contains options"""
|
||||
|
||||
@@ -50,6 +56,7 @@ class ConfigurationGroup(validity.ValidityRoutines):
|
||||
self._options[name] = value
|
||||
raise TypeError("Attribute " + name + " must be an Option object")
|
||||
|
||||
|
||||
class Configuration(validity.ValidityRoutines):
|
||||
"""Class to handle configuration, contains configuration groups"""
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ Created on 6 May 2013
|
||||
"""
|
||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
||||
|
||||
|
||||
class ContextInterface(object):
|
||||
"""All context-like objects must adhere to the following interface.
|
||||
|
||||
@@ -15,13 +16,13 @@ class ContextInterface(object):
|
||||
def __init__(self):
|
||||
"""Initializes the context with a symbol_space"""
|
||||
|
||||
### Symbol Space Functions
|
||||
# ## Symbol Space Functions
|
||||
|
||||
@abstractproperty
|
||||
def symbol_space(self):
|
||||
"""Returns the symbol_space for the context"""
|
||||
|
||||
### Memory Functions
|
||||
# ## Memory Functions
|
||||
|
||||
@abstractproperty
|
||||
def memory(self):
|
||||
@@ -32,15 +33,15 @@ class ContextInterface(object):
|
||||
"""Adds a named translation layer to the context memory"""
|
||||
self.memory.add_layer(layer)
|
||||
|
||||
### Object Factory Functions
|
||||
# ## Object Factory Functions
|
||||
|
||||
@abstractmethod
|
||||
def object(self, symbol, layer_name, offset):
|
||||
"""Object factory, takes a context, symbol, offset and optional layer_name
|
||||
|
||||
|
||||
Looks up the layer_name 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.
|
||||
|
||||
and constructs an object using the object template on the layer at the offset.
|
||||
|
||||
Returns a fully constructed object
|
||||
"""
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from volatility.framework import validity, exceptions
|
||||
from volatility.framework.interfaces import context as context_module
|
||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
||||
|
||||
|
||||
class DataLayerInterface(validity.ValidityRoutines):
|
||||
"""A Layer that directly holds data (and does not translate it"""
|
||||
__metaclass__ = ABCMeta
|
||||
@@ -39,22 +40,21 @@ class DataLayerInterface(validity.ValidityRoutines):
|
||||
@abstractmethod
|
||||
def read(self, offset, length, pad = False):
|
||||
"""Reads an offset for length bytes and returns 'bytes' (not 'str') of length size
|
||||
|
||||
|
||||
If there is a fault of any kind (such as a page fault), an exception will be thrown
|
||||
unless pad is set, in which case the read errors will be replaced by null characters.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def write(self, offset, data):
|
||||
"""Writes a chunk of data at offset.
|
||||
|
||||
"""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):
|
||||
|
||||
@abstractmethod
|
||||
def translate(self, offset):
|
||||
"""Returns a tuple of (offset, layer) indicating the translation of input domain to the output range"""
|
||||
@@ -62,7 +62,7 @@ class TranslationLayerInterface(DataLayerInterface):
|
||||
@abstractmethod
|
||||
def mapping(self, offset, length):
|
||||
"""Returns a sorted list of (offset, mapped_offset, length, layer) mappings
|
||||
|
||||
|
||||
This allows translation layers to provide maps of contiguous regions in one layer
|
||||
"""
|
||||
return []
|
||||
@@ -71,7 +71,7 @@ class TranslationLayerInterface(DataLayerInterface):
|
||||
def dependencies(self):
|
||||
"""Returns a list of layer names that this layer translates onto"""
|
||||
|
||||
### Read/Write functions for mapped pages
|
||||
# ## Read/Write functions for mapped pages
|
||||
|
||||
def read(self, offset, length, pad = False):
|
||||
"""Reads an offset for length bytes and returns 'bytes' (not 'str') of length size"""
|
||||
|
||||
@@ -5,9 +5,11 @@ Created on 6 May 2013
|
||||
"""
|
||||
|
||||
import copy
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
from volatility.framework import validity
|
||||
from volatility.framework.interfaces import context as context_module
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
class ObjectInterface(validity.ValidityRoutines):
|
||||
""" A base object required to be the ancestor of every object used in volatility """
|
||||
@@ -38,11 +40,13 @@ class ObjectInterface(validity.ValidityRoutines):
|
||||
object_template = self._context.symbol_space.resolve(new_structure_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, structure_name = None, **kwargs):
|
||||
"""Stores the keyword arguments for later use"""
|
||||
self._kwargs = kwargs
|
||||
|
||||
@@ -6,6 +6,7 @@ Created on 4 May 2013
|
||||
|
||||
from volatility.framework import validity, exceptions
|
||||
|
||||
|
||||
class SymbolTableInterface(validity.ValidityRoutines):
|
||||
"""Handles a table of symbols"""
|
||||
|
||||
@@ -16,11 +17,11 @@ class SymbolTableInterface(validity.ValidityRoutines):
|
||||
self.name = name or None
|
||||
self._native_structures = native_structures
|
||||
|
||||
### Required Constant symbol functions
|
||||
# ## Required Constant symbol functions
|
||||
|
||||
def get_constant(self, name):
|
||||
"""Resolves a symbol name into a constant
|
||||
|
||||
|
||||
If the symbol isn't found, it raises a SymbolError exception
|
||||
"""
|
||||
raise NotImplementedError("Abstract property get_constant not implemented by subclass.")
|
||||
@@ -30,11 +31,11 @@ class SymbolTableInterface(validity.ValidityRoutines):
|
||||
"""Returns an iterator of the constant symbols"""
|
||||
raise NotImplementedError("Abstract property constants not implemented by subclass.")
|
||||
|
||||
### Required Structure symbol functions
|
||||
# ## Required Structure symbol functions
|
||||
|
||||
def get_structure(self, name):
|
||||
"""Resolves a symbol name into an object template
|
||||
|
||||
|
||||
If the symbol isn't found it raises a SymbolError exception
|
||||
"""
|
||||
raise NotImplementedError("Abstract method get_structure not implemented by subclass.")
|
||||
@@ -44,7 +45,7 @@ class SymbolTableInterface(validity.ValidityRoutines):
|
||||
"""Returns an iterator of the structure symbols"""
|
||||
raise NotImplementedError("Abstract property structures not implemented by subclass.")
|
||||
|
||||
### Native Type Handler
|
||||
# ## Native Type Handler
|
||||
|
||||
@property
|
||||
def natives(self):
|
||||
@@ -68,10 +69,11 @@ class SymbolTableInterface(validity.ValidityRoutines):
|
||||
"""Removes the associated class override for a specific structure symbol"""
|
||||
raise NotImplementedError("Abstract method del_structure_class not implemented yet.")
|
||||
|
||||
# ### Helper functions that can be overridden
|
||||
|
||||
# ### Helper functions that can be overridden
|
||||
#
|
||||
# def __len__(self):
|
||||
# """Returns the number of items in the symbol list"""
|
||||
# def __len__(self):
|
||||
# """Returns the number of items in the symbol list"""
|
||||
# return len(self.structures)
|
||||
#
|
||||
# def __getitem__(self, key):
|
||||
@@ -93,7 +95,7 @@ class NativeTableInterface(SymbolTableInterface):
|
||||
"""Class to distinguish NativeSymbolLists from other symbol lists"""
|
||||
|
||||
@staticmethod
|
||||
def constant(self):
|
||||
def constant():
|
||||
raise exceptions.SymbolError("NativeTables never hold constants")
|
||||
|
||||
@property
|
||||
|
||||
@@ -7,6 +7,7 @@ Created on 4 May 2013
|
||||
from volatility.framework import validity, interfaces, exceptions
|
||||
from volatility.framework.layers import physical, intel
|
||||
|
||||
|
||||
class Memory(validity.ValidityRoutines):
|
||||
"""Container for multiple layers of data"""
|
||||
|
||||
@@ -15,7 +16,7 @@ class Memory(validity.ValidityRoutines):
|
||||
|
||||
def read(self, layer, offset, length, pad = False):
|
||||
"""Reads from a particular layer at offset for length bytes
|
||||
|
||||
|
||||
Returns 'bytes' not 'str'
|
||||
"""
|
||||
return self[layer].read(offset, length, pad)
|
||||
@@ -26,7 +27,7 @@ class Memory(validity.ValidityRoutines):
|
||||
|
||||
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, interfaces.layers.DataLayerInterface)
|
||||
@@ -41,7 +42,7 @@ class Memory(validity.ValidityRoutines):
|
||||
|
||||
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:
|
||||
|
||||
@@ -6,8 +6,10 @@ Created on 7 May 2013
|
||||
|
||||
import math
|
||||
import struct
|
||||
|
||||
from volatility.framework import interfaces, exceptions
|
||||
|
||||
|
||||
class Intel(interfaces.layers.TranslationLayerInterface):
|
||||
"""Translation Layer for the Intel IA32 memory mapping"""
|
||||
|
||||
@@ -43,7 +45,7 @@ class Intel(interfaces.layers.TranslationLayerInterface):
|
||||
|
||||
def _translate(self, offset):
|
||||
"""Translates a specific offset based on paging tables
|
||||
|
||||
|
||||
Returns the offset and the pagesize
|
||||
"""
|
||||
# Setup the entry and how far we are through the offset
|
||||
@@ -88,7 +90,7 @@ class Intel(interfaces.layers.TranslationLayerInterface):
|
||||
|
||||
def mapping(self, offset, length):
|
||||
"""Returns a sorted list of (offset, mapped_offset, length, layer) mappings
|
||||
|
||||
|
||||
This allows translation layers to provide maps of contiguous regions in one layer
|
||||
"""
|
||||
result = []
|
||||
@@ -100,6 +102,7 @@ class Intel(interfaces.layers.TranslationLayerInterface):
|
||||
result.append((chunk_offset, chunk_size))
|
||||
return result
|
||||
|
||||
|
||||
class IntelPAE(Intel):
|
||||
"""Class for handling Physical Address Extensions for Intel architectures"""
|
||||
|
||||
@@ -116,8 +119,8 @@ class IntelPAE(Intel):
|
||||
('page directory', 9, True),
|
||||
('page table', 9, True)]
|
||||
|
||||
class Intel32e(Intel):
|
||||
|
||||
class Intel32e(Intel):
|
||||
def __init__(self, *args, **kwargs):
|
||||
Intel.__init__(self, *args, **kwargs)
|
||||
|
||||
@@ -132,17 +135,17 @@ class Intel32e(Intel):
|
||||
('page directory', 9, True),
|
||||
('page table', 9, True)]
|
||||
|
||||
class WindowsMixin(object):
|
||||
|
||||
class WindowsMixin(object):
|
||||
@staticmethod
|
||||
def _page_is_valid(entry):
|
||||
"""Returns whether a particular page is valid based on its entry
|
||||
|
||||
|
||||
Windows uses additional "available" bits to store flags
|
||||
These flags allow windows to determine whether a page is still valid
|
||||
|
||||
|
||||
Bit 11 is the transition flag, and Bit 10 is the prototype flag
|
||||
|
||||
|
||||
For more information, see Windows Internals (6th Ed, Part 2, pages 268-269)
|
||||
"""
|
||||
return (entry & 1) or ((entry & 1 << 11) and not (entry & 1 << 10))
|
||||
return (entry & 1) or ((entry & 1 << 11) and not entry & 1 << 10)
|
||||
|
||||
@@ -5,8 +5,10 @@ Created on 6 May 2013
|
||||
"""
|
||||
|
||||
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"""
|
||||
|
||||
@@ -37,6 +39,7 @@ class BufferDataLayer(interfaces.layers.DataLayerInterface):
|
||||
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"""
|
||||
|
||||
@@ -81,7 +84,7 @@ class FileLayer(interfaces.layers.DataLayerInterface):
|
||||
|
||||
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):
|
||||
|
||||
@@ -6,11 +6,14 @@ Created on 17 Feb 2013
|
||||
|
||||
import struct
|
||||
import collections
|
||||
|
||||
from volatility.framework import interfaces
|
||||
from volatility.framework.objects import templates
|
||||
|
||||
|
||||
class Void(interfaces.objects.ObjectInterface):
|
||||
"""Returns an object to represent void/unknown types"""
|
||||
|
||||
@classmethod
|
||||
def template_size(cls, arguments):
|
||||
"""Dummy size for Void objects"""
|
||||
@@ -25,6 +28,7 @@ class Void(interfaces.objects.ObjectInterface):
|
||||
def template_replace_child(cls, old_child, new_child, arguments):
|
||||
"""Dummy method that does nothing for Void objects"""
|
||||
|
||||
|
||||
class PrimitiveObject(interfaces.objects.ObjectInterface):
|
||||
"""PrimitiveObject is an interface for any objects that should simulate a Python primitive"""
|
||||
|
||||
@@ -59,6 +63,7 @@ class PrimitiveObject(interfaces.objects.ObjectInterface):
|
||||
def template_replace_child(cls, old_child, new_child, arguments):
|
||||
"""Since this template can't ever have children, this method can be empty"""
|
||||
|
||||
|
||||
class Integer(PrimitiveObject, int):
|
||||
"""Primitive Object that handles standard numeric types"""
|
||||
|
||||
@@ -72,6 +77,7 @@ class Integer(PrimitiveObject, int):
|
||||
return self._context.memory.write(self._layer_name, self._offset, data)
|
||||
raise TypeError("Integer objects require an integer to be written")
|
||||
|
||||
|
||||
class Float(PrimitiveObject, float):
|
||||
"""Primitive Object that handles double or floating point numbers"""
|
||||
|
||||
@@ -85,6 +91,7 @@ class Float(PrimitiveObject, float):
|
||||
return self._context.memory.write(self._layer_name, self._offset, data)
|
||||
raise TypeError("Float objects require a float to be written")
|
||||
|
||||
|
||||
class Bytes(PrimitiveObject, bytes):
|
||||
"""Primitive Object that handles specific series of bytes"""
|
||||
|
||||
@@ -104,9 +111,10 @@ class Bytes(PrimitiveObject, bytes):
|
||||
return self._context.memory.write(self._layer_name, self._offset, data)
|
||||
raise TypeError("Bytes objects require a bytes type to be written")
|
||||
|
||||
|
||||
class String(PrimitiveObject, str):
|
||||
"""Primitive Object that handles string values
|
||||
|
||||
|
||||
length: specifies the maximum possible length that the string could hold in memory
|
||||
"""
|
||||
|
||||
@@ -126,8 +134,10 @@ class String(PrimitiveObject, str):
|
||||
return self._context.memory.write(self._layer_name, self._offset, data)
|
||||
raise TypeError("String objects require a string to be written")
|
||||
|
||||
|
||||
class Pointer(Integer):
|
||||
"""Pointer which points to another object"""
|
||||
|
||||
def __init__(self, context, layer_name, offset, structure_name, size = None,
|
||||
parent = None, struct_format = None, target = None):
|
||||
if not isinstance(target, templates.ObjectTemplate):
|
||||
@@ -170,8 +180,10 @@ class Pointer(Integer):
|
||||
if arguments['target'] == old_child:
|
||||
arguments['target'] = new_child
|
||||
|
||||
|
||||
class BitField(PrimitiveObject, int):
|
||||
"""Object containing a field which is made up of bits rather than whole bytes"""
|
||||
|
||||
def __new__(cls, context, layer_name, offset, structure_name, size = None,
|
||||
parent = None, target = None, start_bit = 0, end_bit = 0, **kwargs):
|
||||
value = target(context = context,
|
||||
@@ -192,6 +204,7 @@ class BitField(PrimitiveObject, int):
|
||||
def write(self, value):
|
||||
raise NotImplementedError("Writing to BitFields is not yet implemented")
|
||||
|
||||
|
||||
class Enumeration(interfaces.objects.ObjectInterface):
|
||||
"""Returns an object made up of choices"""
|
||||
# FIXME: Add in body for the enumeration object
|
||||
@@ -202,8 +215,10 @@ class Enumeration(interfaces.objects.ObjectInterface):
|
||||
def write(self, value):
|
||||
raise NotImplementedError("Writing to Enumerations is not yet implemented")
|
||||
|
||||
|
||||
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, structure_name, size = None,
|
||||
parent = None, count = 0, target = None):
|
||||
if not isinstance(target, templates.ObjectTemplate):
|
||||
@@ -251,6 +266,7 @@ class Array(interfaces.objects.ObjectInterface, collections.Sequence):
|
||||
def write(self, value):
|
||||
raise NotImplementedError("Writing to Arrays is not yet implemented")
|
||||
|
||||
|
||||
class Struct(interfaces.objects.ObjectInterface):
|
||||
"""Object which can contain members that are other objects"""
|
||||
|
||||
|
||||
@@ -6,15 +6,17 @@ Created on 1 Mar 2013
|
||||
|
||||
from volatility.framework import interfaces, validity
|
||||
|
||||
|
||||
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.
|
||||
It also allows inspection of information that should already be known:
|
||||
* Structure size
|
||||
* Members, etc
|
||||
etc.
|
||||
"""
|
||||
|
||||
def __init__(self, object_class = None, structure_name = None, **kwargs):
|
||||
interfaces.objects.Template.__init__(self, structure_name = structure_name, **kwargs)
|
||||
self.class_check(object_class, interfaces.objects.ObjectInterface)
|
||||
@@ -36,34 +38,37 @@ class ObjectTemplate(interfaces.objects.Template, validity.ValidityRoutines):
|
||||
@property
|
||||
def children(self):
|
||||
"""A function that returns a list of child templates of a template
|
||||
|
||||
|
||||
This is used to traverse the template tree
|
||||
"""
|
||||
return self.object_class.template_children(self._kwargs)
|
||||
|
||||
def replace_child(self, old_child, new_child):
|
||||
"""A function for replacing one child with another
|
||||
|
||||
|
||||
We pass in the kwargs directly so they can be changed
|
||||
"""
|
||||
self.object_class.template_replace_child(old_child, new_child, self._kwargs)
|
||||
|
||||
def __call__(self, context, layer_name, offset, parent = None):
|
||||
"""Constructs the object
|
||||
|
||||
Returns: an object adhereing to the Object interface
|
||||
|
||||
Returns: an object adhereing to the Object interface
|
||||
"""
|
||||
# We always use the template size (as calculated by the object class)
|
||||
# over the one passed in by an argument
|
||||
self._kwargs['size'] = self.size
|
||||
self._kwargs['structure_name'] = self.structure_name
|
||||
return self.object_class(context = context, layer_name = layer_name, offset = offset, parent = parent, **self._kwargs)
|
||||
return self.object_class(context = context, layer_name = layer_name, offset = offset, parent = parent,
|
||||
**self._kwargs)
|
||||
|
||||
|
||||
class ReferenceTemplate(interfaces.objects.Template):
|
||||
"""Factory class that produces objects based on a delayed reference type
|
||||
|
||||
It should not return any attributes
|
||||
|
||||
It should not return any attributes
|
||||
"""
|
||||
|
||||
def __call__(self, context, *args, **kwargs):
|
||||
template = context.symbol_space.get_structure(self._structure_name)
|
||||
return template(context = context, *args, **kwargs)
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
|
||||
|
||||
# TODO: Code to import all the py/pyc files available (but not both).
|
||||
# TODO: Code to return a none-instantiated list of plugin classes.
|
||||
# TODO: Code to return a none-instantiated list of plugin classes.
|
||||
|
||||
@@ -82,8 +82,8 @@ class TreeGrid(TreeRow):
|
||||
converted_columns = []
|
||||
for (name, column_type, column_format) in columns:
|
||||
is_simple_type = False
|
||||
for t in self.simple_types:
|
||||
is_simple_type = is_simple_type or issubclass(column_type, t)
|
||||
for stype in self.simple_types:
|
||||
is_simple_type = is_simple_type or issubclass(column_type, stype)
|
||||
if not is_simple_type:
|
||||
raise TypeError("Column " + name + "'s type " + column_type.__class__.__name__ +
|
||||
" is not a simple type")
|
||||
@@ -135,7 +135,7 @@ class FormatSpecification(object):
|
||||
|
||||
# noinspection PyShadowingBuiltins
|
||||
def __init__(self, fill = None, align = None, sign = None, alt = None, zero = None, width = None,
|
||||
precision = None, type = None):
|
||||
precision = None, type = None): # pylint: disable=W0622
|
||||
self._fill = fill
|
||||
self._align = align
|
||||
self._sign = sign
|
||||
@@ -297,4 +297,4 @@ class FormatSpecification(object):
|
||||
(str(self.width) if self.width else '') +
|
||||
(("." + str(self.precision)) if self.precision or self.precision == 0 else '') +
|
||||
(self.type or ''))
|
||||
return spec
|
||||
return spec
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
from framework.renderers import FormatSpecification
|
||||
|
||||
__author__ = 'mike'
|
||||
|
||||
import sys
|
||||
|
||||
from volatility.framework.interfaces import renderers as interface
|
||||
from volatility.framework import renderers
|
||||
import sys
|
||||
|
||||
|
||||
class TextRenderer(interface.Renderer):
|
||||
@@ -40,8 +39,9 @@ class TextRenderer(interface.Renderer):
|
||||
# Then print out the headers and the values at their appropriate spacings
|
||||
# Potentially warn if the output is likely to be longer than the display area.
|
||||
|
||||
headers = [("{0:" + FormatSpecification(width = column_maximum_widths[column.index], fill = ' ',
|
||||
align = '^').to_string() + "}").format(column.name) for column in
|
||||
headers = [("{0:" + renderers.FormatSpecification(width = column_maximum_widths[column.index], fill = ' ',
|
||||
align = '^').to_string() + "}").format(column.name) for column
|
||||
in
|
||||
grid.columns]
|
||||
print(sep.join(headers))
|
||||
|
||||
@@ -50,4 +50,4 @@ class TextRenderer(interface.Renderer):
|
||||
for column in grid.columns:
|
||||
row_text.append(("{:" + column.format.to_string() + "}").format(row.values[column.index]))
|
||||
line = sep.join(row_text)
|
||||
sys.stdout.write(line + "\n")
|
||||
sys.stdout.write(line + "\n")
|
||||
|
||||
@@ -5,11 +5,13 @@ Created on 7 Feb 2013
|
||||
'''
|
||||
|
||||
import collections
|
||||
|
||||
from volatility.framework import objects, interfaces, exceptions
|
||||
|
||||
|
||||
class SymbolSpace(collections.Mapping):
|
||||
"""Handles an ordered collection of SymbolTables
|
||||
|
||||
|
||||
This collection is ordered so that resolution of symbols can
|
||||
proceed down through the ranks if a namespace isn't specified.
|
||||
"""
|
||||
@@ -63,7 +65,7 @@ class SymbolSpace(collections.Mapping):
|
||||
|
||||
def get_structure(self, symbol):
|
||||
"""Takes a symbol name and resolves it
|
||||
|
||||
|
||||
This method ensures that all referenced templates (including self-referential templates)
|
||||
are satisfied as ObjectTemplates
|
||||
"""
|
||||
|
||||
@@ -4,8 +4,10 @@ Created on 10 Apr 2013
|
||||
@author: mike
|
||||
'''
|
||||
import copy
|
||||
|
||||
from volatility.framework import objects, interfaces
|
||||
|
||||
|
||||
class NativeTable(interfaces.symbols.NativeTableInterface):
|
||||
"""Symbol List that handles Native types"""
|
||||
|
||||
@@ -18,7 +20,7 @@ class NativeTable(interfaces.symbols.NativeTableInterface):
|
||||
self._overrides[native_type] = native_class
|
||||
# Create this once early, because it may get used a lot
|
||||
self._structures = set(self._native_dictionary.keys()).union(
|
||||
{'Enumeration', 'array', 'BitField', 'void', 'pointer'})
|
||||
set(['Enumeration', 'array', 'BitField', 'void', 'pointer']))
|
||||
|
||||
def get_structure_class(self, name):
|
||||
ntype, fmt = native_types.get(name, (objects.Integer, ''))
|
||||
@@ -31,43 +33,47 @@ class NativeTable(interfaces.symbols.NativeTableInterface):
|
||||
|
||||
def get_structure(self, structure_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 structure_name == 'void':
|
||||
return objects.templates.ObjectTemplate(objects.Void, structure_name = structure_name)
|
||||
elif structure_name == 'array':
|
||||
return objects.templates.ObjectTemplate(objects.Array, structure_name = structure_name, count = 0, target = self.get_structure('void'))
|
||||
return objects.templates.ObjectTemplate(objects.Array, structure_name = structure_name, count = 0,
|
||||
target = self.get_structure('void'))
|
||||
elif structure_name == 'Enumeration':
|
||||
return objects.templates.ObjectTemplate(objects.Enumeration, structure_name = structure_name, target = self.get_structure('void'), choices = {})
|
||||
return objects.templates.ObjectTemplate(objects.Enumeration, structure_name = structure_name,
|
||||
target = self.get_structure('void'), choices = {})
|
||||
elif structure_name == 'BitField':
|
||||
return objects.templates.ObjectTemplate(objects.BitField, structure_name = structure_name, start_bit = 0, end_bit = 0)
|
||||
return objects.templates.ObjectTemplate(objects.BitField, structure_name = structure_name, start_bit = 0,
|
||||
end_bit = 0)
|
||||
|
||||
_native_type, native_format = self._native_dictionary[structure_name]
|
||||
if structure_name == 'pointer':
|
||||
additional = {'target': self.get_structure('void')}
|
||||
return objects.templates.ObjectTemplate(self.get_structure_class(structure_name), #pylint: disable-msg=W0142
|
||||
structure_name = structure_name,
|
||||
struct_format = native_format,
|
||||
**additional)
|
||||
return objects.templates.ObjectTemplate(self.get_structure_class(structure_name), # pylint: disable=W0142
|
||||
structure_name = structure_name,
|
||||
struct_format = native_format,
|
||||
**additional)
|
||||
|
||||
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")}
|
||||
|
||||
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'] = (objects.Pointer, '<Q')
|
||||
x64NativeTable = NativeTable("native", native_types)
|
||||
|
||||
@@ -5,33 +5,35 @@ Created on 10 Apr 2013
|
||||
'''
|
||||
|
||||
import copy
|
||||
|
||||
from volatility.framework import exceptions, objects, interfaces
|
||||
|
||||
### TODO
|
||||
#
|
||||
# All symbol lists should take a label to an object template
|
||||
#
|
||||
# Templates for targets etc should be looked up recursively just like anything else
|
||||
# We therefore need a way to unroll rolled-up types
|
||||
# Generate mangled names on the fly (prohibits external calling)
|
||||
#
|
||||
# Symbol list could be a dict with knowledge of its parent?
|
||||
# Class split is arbitrary, it's an extension for developers
|
||||
# Object template should contain both class and initial parameters
|
||||
#
|
||||
#
|
||||
# *** Resolution should not happen in the resolve function
|
||||
# It should only happen on access of contained types ***
|
||||
#
|
||||
# Recursive objects can be fixed by having caching the objects
|
||||
# (however, they have to be built first!)
|
||||
#
|
||||
# Single hop resolution is probably the solution
|
||||
# Could probably deal iwth it by having a property that caches
|
||||
# for container types
|
||||
#
|
||||
# Need to figure out how to tell the difference for vtypes between
|
||||
# vtype list and a struct dictionary
|
||||
|
||||
# ## TODO
|
||||
#
|
||||
# All symbol lists should take a label to an object template
|
||||
#
|
||||
# Templates for targets etc should be looked up recursively just like anything else
|
||||
# We therefore need a way to unroll rolled-up types
|
||||
# Generate mangled names on the fly (prohibits external calling)
|
||||
#
|
||||
# Symbol list could be a dict with knowledge of its parent?
|
||||
# Class split is arbitrary, it's an extension for developers
|
||||
# Object template should contain both class and initial parameters
|
||||
#
|
||||
#
|
||||
# *** Resolution should not happen in the resolve function
|
||||
# It should only happen on access of contained types ***
|
||||
#
|
||||
# Recursive objects can be fixed by having caching the objects
|
||||
# (however, they have to be built first!)
|
||||
#
|
||||
# Single hop resolution is probably the solution
|
||||
# Could probably deal iwth it by having a property that caches
|
||||
# for container types
|
||||
#
|
||||
# Need to figure out how to tell the difference for vtypes between
|
||||
# vtype list and a struct dictionary
|
||||
|
||||
class VTypeSymbolTable(interfaces.symbols.SymbolTableInterface):
|
||||
"""Symbol Table that handles vtype datastructures"""
|
||||
@@ -77,7 +79,7 @@ class VTypeSymbolTable(interfaces.symbols.SymbolTableInterface):
|
||||
elif structure_name == 'BitField':
|
||||
update = dictionary[1]
|
||||
update['target'] = self._vtypedict_to_template([update['native_type']])
|
||||
native_template.update_arguments(**update) #pylint: disable-msg=W0142
|
||||
native_template.update_arguments(**update) # pylint: disable=W0142
|
||||
return native_template
|
||||
|
||||
# Otherwise
|
||||
@@ -102,4 +104,5 @@ class VTypeSymbolTable(interfaces.symbols.SymbolTableInterface):
|
||||
member = (relative_offset, self._vtypedict_to_template(vtypedict))
|
||||
members[member_name] = member
|
||||
object_class = self.get_structure_class(structure_name)
|
||||
return objects.templates.ObjectTemplate(object_class = object_class, structure_name = structure_name, size = size, members = members)
|
||||
return objects.templates.ObjectTemplate(object_class = object_class, structure_name = structure_name,
|
||||
size = size, members = members)
|
||||
|
||||
@@ -4,6 +4,7 @@ Created on 4 May 2013
|
||||
@author: mike
|
||||
"""
|
||||
|
||||
|
||||
class ValidityRoutines(object):
|
||||
"""Class to hold all validation routines, such as type checking"""
|
||||
|
||||
@@ -30,7 +31,7 @@ class ValidityRoutines(object):
|
||||
assert issubclass(klass, valid_class), self.__class__.__name__ + " expected " + \
|
||||
valid_class.__name__ + ", not " + klass.__name__
|
||||
|
||||
def confirm(assertion, error):
|
||||
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:
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
"""Defines the plugin architecture
|
||||
|
||||
This is the namespace for all volatility plugins,
|
||||
and determines the path for loading plugins
|
||||
"""
|
||||
import volatility.framework.constants as constants
|
||||
|
||||
__path__ = constants.PLUGINS_PATH
|
||||
__path__ = constants.PLUGINS_PATH
|
||||
|
||||
@@ -1 +1 @@
|
||||
__author__ = 'mike'
|
||||
"""All Linux-related plugins"""
|
||||
|
||||
@@ -1 +1 @@
|
||||
__author__ = 'mike'
|
||||
"""All Windows OS plugins"""
|
||||
|
||||
Reference in New Issue
Block a user