mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-30 05:24:52 +02:00
Add in UnresolvedTemplate type.
This template type allows objects that have not been able to be resolved to exist within the symbol system. It emits a debug message on creation so that intermediate format developers can identify potential issues, but does not raise an exception so as to allow partial tables to be used. If the UnresolvedTemplate is called (to create an object) before the symbol has been added to the symbolspace, it will fail with a SymbolError (as thrown by the individual SymbolTable). For this reason, the class has been made private to the SymbolSpace class to prevent unexpected use.
This commit is contained in:
@@ -132,6 +132,30 @@ class Template(validity.ValidityRoutines):
|
||||
"""Returns a volatility information object, much like the ObjectInterface provides"""
|
||||
return ReadOnlyMapping(self._vol)
|
||||
|
||||
@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 []
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def size(self):
|
||||
"""Returns the size of the template"""
|
||||
|
||||
@abstractmethod
|
||||
def relative_child_offset(self, child):
|
||||
"""A function that returns the relative offset of a child from its parent offset
|
||||
|
||||
This may throw exceptions including ChildNotFoundException and NotImplementedError
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def replace_child(self, old_child, new_child):
|
||||
"""A function for replacing one child with another"""
|
||||
|
||||
def update_vol(self, **new_arguments):
|
||||
"""Updates the keyword arguments"""
|
||||
self._vol.update(new_arguments)
|
||||
|
||||
@@ -3,8 +3,12 @@ Created on 1 Mar 2013
|
||||
|
||||
@author: mike
|
||||
"""
|
||||
import logging
|
||||
|
||||
from volatility.framework import interfaces, validity
|
||||
from volatility.framework.exceptions import SymbolError
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ObjectTemplate(interfaces.objects.Template, validity.ValidityRoutines):
|
||||
@@ -44,8 +48,6 @@ class ObjectTemplate(interfaces.objects.Template, validity.ValidityRoutines):
|
||||
|
||||
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
|
||||
"""
|
||||
return self.vol.object_class.VolTemplateProxy.replace_child(self, old_child, new_child)
|
||||
|
||||
@@ -68,6 +70,20 @@ class ReferenceTemplate(interfaces.objects.Template):
|
||||
It should not return any attributes
|
||||
"""
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
return []
|
||||
|
||||
@property
|
||||
def _unresolved(self, *args, **kwargs):
|
||||
"""Referenced symbols must be appropriately resolved before they can provide information such as size
|
||||
This is because the size request has no context within which to determine the actual symbol structure.
|
||||
"""
|
||||
raise SymbolError("Template {0} contains no information about its structure".format(self.vol.type_name))
|
||||
|
||||
size = property(_unresolved)
|
||||
replace_child = relative_child_offset = _unresolved
|
||||
|
||||
def __call__(self, context, object_info):
|
||||
template = context.symbol_space.get_type(self.vol.type_name)
|
||||
return template(context = context, object_info = object_info)
|
||||
|
||||
@@ -6,11 +6,14 @@ Created on 7 Feb 2013
|
||||
|
||||
import collections
|
||||
import collections.abc
|
||||
import logging
|
||||
import warnings
|
||||
|
||||
from volatility.framework import objects, interfaces, exceptions, constants
|
||||
from volatility.framework import constants, exceptions, interfaces, objects
|
||||
from volatility.framework.symbols import native, vtypes, windows
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SymbolType(object):
|
||||
# Suitably random values until we make this an Enum and require python >= 3.4
|
||||
@@ -33,6 +36,8 @@ class SymbolSpace(collections.abc.Mapping):
|
||||
# Permanently cache all resolved symbols
|
||||
self._resolved = {}
|
||||
|
||||
### Symbol functions
|
||||
|
||||
def get_symbols_by_type(self, type_name):
|
||||
"""Returns all symbols based """
|
||||
for table in self._dict.keys():
|
||||
@@ -51,6 +56,8 @@ class SymbolSpace(collections.abc.Mapping):
|
||||
for symbol_name in self._dict[table].get_symbols_by_location(address = address):
|
||||
yield table + constants.BANG + symbol_name
|
||||
|
||||
### Native functions
|
||||
|
||||
@property
|
||||
def natives(self):
|
||||
"""Returns the native_types for this symbol space"""
|
||||
@@ -63,6 +70,8 @@ class SymbolSpace(collections.abc.Mapping):
|
||||
"Resetting the native type can cause have drastic effects on memory analysis using this space")
|
||||
self._native_types = native_types
|
||||
|
||||
### Space functions
|
||||
|
||||
def __len__(self):
|
||||
"""Returns the number of tables within the space"""
|
||||
return len(self._dict)
|
||||
@@ -89,6 +98,23 @@ class SymbolSpace(collections.abc.Mapping):
|
||||
self._resolved = {}
|
||||
del self._dict[key]
|
||||
|
||||
### Resolution functions
|
||||
|
||||
class _UnresolvedTemplate(objects.templates.ReferenceTemplate):
|
||||
"""Class to highlight when missing symbols are present
|
||||
|
||||
This class is identical to a reference template, but differentiable by its classname.
|
||||
It will output a debug log to indicate when it has been instantiated and with what name.
|
||||
|
||||
This class is designed to be output ONLY as part of the SymbolSpace resolution system.
|
||||
Individual SymbolTables that cannot resolve a symbol should still return a SymbolError to
|
||||
indicate this failure in resolution.
|
||||
"""
|
||||
|
||||
def __init__(self, type_name = None, **kwargs):
|
||||
vollog.debug("Unresolved symbol referenced: {0}".format(type_name))
|
||||
super().__init__(type_name = type_name, **kwargs)
|
||||
|
||||
def _weak_resolve(self, resolve_type, name):
|
||||
"""Takes a symbol name and resolves it with ReferentialTemplates"""
|
||||
if resolve_type == SymbolType.TYPE:
|
||||
@@ -102,7 +128,10 @@ class SymbolSpace(collections.abc.Mapping):
|
||||
if len(name_array) == 2:
|
||||
table_name = name_array[0]
|
||||
component_name = name_array[1]
|
||||
return getattr(self._dict[table_name], get_function)(component_name)
|
||||
try:
|
||||
return getattr(self._dict[table_name], get_function)(component_name)
|
||||
except (exceptions.SymbolError, KeyError):
|
||||
return self._UnresolvedTemplate(name)
|
||||
elif name in self.natives.types:
|
||||
return getattr(self.natives, get_function)(name)
|
||||
raise exceptions.SymbolError("Malformed symbol name: " + repr(name))
|
||||
|
||||
Reference in New Issue
Block a user