Files
volatility3/volatility/framework/interfaces/symbols.py
T
Mike Auty 14c0cc262c Significantly rework the configuration system.
So this is where I ripped out the guts of the dependency tree
and made it a little better defined in some ways, and delayed
populating it in others.  The validate function signature has
changed and I'm still up in the air whether to validate with
True/False or throw/catch exceptions.

So now, configurables have a list of requirements, these are
then bundled into a single requirement and can be passed to
automagic.  Automagic runs a set of things over the deptree
to help build/manage it.  These run in order of priority.

The tree is still built from the top down, but now automagic
can build branch from the bottom up and try and splice them
into the tree where appropriate.  Hopefully this will make it
easier to see follow.
2016-07-29 03:24:52 +01:00

149 lines
5.1 KiB
Python

"""
Created on 4 May 2013
@author: mike
"""
import bisect
from volatility.framework import validity, exceptions, constants
from volatility.framework.interfaces import configuration
class Symbol(validity.ValidityRoutines):
def __init__(self, name, offset, type_name = None):
self._name = self._check_type(name, str)
if constants.BANG in self._name:
raise ValueError("Symbol names cannot contain the symbol differentiator (" + constants.BANG + ")")
self._location = None
self._offset = self._check_type(offset, int)
if type_name is None:
type_name = name
self._type_name = self._check_type(type_name, str)
# Scope and location can be added at a later date
@property
def name(self):
"""Returns the name of the symbol"""
return self._name
@property
def type_name(self):
"""Returns the name of the type that the symbol represents"""
return self._type_name
@property
def offset(self):
"""Returns the relative offset of the symbol within the compilation unit"""
return self._offset
class SymbolTableInterface(validity.ValidityRoutines):
"""Handles a table of symbols"""
def __init__(self, name, native_types = None):
self._check_type(native_types, NativeTableInterface)
if name:
self._check_type(name, str)
self.name = name or None
self._native_types = native_types
# ## Required Symbol functions
def get_symbol(self, name):
"""Resolves a symbol name into a symbol object
If the symbol isn't found, it raises a SymbolError exception
"""
raise NotImplementedError("Abstract property get_symbol not implemented by subclass.")
@property
def symbols(self):
"""Returns an iterator of the Symbols"""
raise NotImplementedError("Abstract property symbols not implemented by subclass.")
# ## Required Symbol type functions
def get_type(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_type not implemented by subclass.")
@property
def types(self):
"""Returns an iterator of the Symbol types"""
raise NotImplementedError("Abstract property types not implemented by subclass.")
# ## Native Type Handler
@property
def natives(self):
"""Returns None or a NativeTable for handling space specific native types"""
return self._native_types
@natives.setter
def natives(self, value):
"""Checks the natives value and then applies it internally
WARNING: This allows changing the underlying size of all the other types referenced in the SymbolTable
"""
self._check_type(value, NativeTableInterface)
self._native_types = value
# ## Functions for overriding classes
def set_type_class(self, name, clazz):
"""Overrides the object class for a specific Symbol type
Name *must* be present in self.types
"""
raise NotImplementedError("Abstract method set_type_class not implemented yet.")
def get_type_class(self, name):
"""Returns the class associated with a Symbol type"""
raise NotImplementedError("Abstract method get_type_class not implemented yet.")
def del_type_class(self, name):
"""Removes the associated class override for a specific Symbol type"""
raise NotImplementedError("Abstract method del_type_class not implemented yet.")
# ## Convenience functions for location symbols
def get_symbol_type(self, name):
"""Resolves a symbol name into a symbol and then resolves the symbol's type"""
return self.get_type(self.get_symbol(name).type_name)
def get_symbols_by_type(self, type_name):
"""Returns the name of all symbols in this table that have type matching type_name"""
for symbol in self.symbols:
# This allows for searching with and without the table name (in case multiple tables contain
# the same symbol name and we've not specifically been told which one)
if symbol.type_name == type_name or (symbol.type_name.endswith(constants.BANG + type_name)):
yield symbol.name
def get_symbols_by_location(self, offset):
"""Returns the name of all symbols in this table that have type matching type_name"""
sort_symbols = [(s.offset, s) for s in sorted(self.symbols, key = lambda x: x.offset)]
result = bisect.bisect_left(sort_symbols, offset)
if result == len(sort_symbols):
raise StopIteration
closest_symbol = sort_symbols[result][1]
if closest_symbol.offset == offset:
yield closest_symbol.name
class NativeTableInterface(SymbolTableInterface):
"""Class to distinguish NativeSymbolLists from other symbol lists"""
def get_symbol(self, name):
raise exceptions.SymbolError("NativeTables never hold symbols")
@property
def symbols(self):
return []
class SymbolTableProviderInterface(configuration.ConfigurableInterface):
pass