mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-10-01 14:04:54 +02:00
Fix broken type resolution
The introduction of symbol resolution required subresolving "unnamed" (symbol named) types. The resolution system was changed to pass constructed objects rather than names, which prevented the referencing from working properly. This commit changes that bit back and creates a temporary *type* in the _resolved list for the symbol, then restores whatever was there before. We restore it so that people don't get used to looking up symbols using get_type (we may revisit this decision).
This commit is contained in:
@@ -5,7 +5,6 @@ import logging
|
||||
import typing
|
||||
|
||||
from volatility.framework import constants, exceptions, interfaces, objects, validity
|
||||
from volatility.framework.objects import templates
|
||||
from volatility.framework.symbols import native, windows, linux
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
@@ -35,6 +34,7 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface, validity.ValidityRout
|
||||
self._dict = collections.OrderedDict() # type: typing.Dict[str, interfaces.symbols.BaseSymbolTableInterface]
|
||||
# Permanently cache all resolved symbols
|
||||
self._resolved = {} # type: typing.Dict[str, interfaces.objects.Template]
|
||||
self._resolved_symbols = set() # type: typing.Set[str]
|
||||
|
||||
def free_table_name(self, prefix: str = "layer") -> str:
|
||||
"""Returns an unused table name to ensure no collision occurs when inserting a symbol table"""
|
||||
@@ -131,12 +131,12 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface, validity.ValidityRout
|
||||
raise exceptions.SymbolError('Type {} references missing Type/Symbol/Enum: {}'.format(name, e))
|
||||
raise exceptions.SymbolError("Malformed name: {}".format(name))
|
||||
|
||||
def _recursive_resolve(self, traverse_list):
|
||||
"""Recursively resolves a type, populating linked child ReferenceTemplates with their properly resolved counterparts"""
|
||||
def _iterative_resolve(self, traverse_list):
|
||||
"""Iteratively resolves a type, populating linked child ReferenceTemplates with their properly resolved counterparts"""
|
||||
replacements = set()
|
||||
# Whole Symbols that still need traversing
|
||||
while traverse_list:
|
||||
template_traverse_list, traverse_list = [traverse_list[0]], traverse_list[1:]
|
||||
template_traverse_list, traverse_list = [self._resolved[traverse_list[0]]], traverse_list[1:]
|
||||
# Traverse a single symbol looking for any ReferenceTemplate objects
|
||||
while template_traverse_list:
|
||||
traverser, template_traverse_list = template_traverse_list[0], template_traverse_list[1:]
|
||||
@@ -145,7 +145,7 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface, validity.ValidityRout
|
||||
# If we haven't seen it before, subresolve it and also add it
|
||||
# to the "symbols that still need traversing" list
|
||||
if child.vol.type_name not in self._resolved:
|
||||
traverse_list.append(child)
|
||||
traverse_list.append(child.vol.type_name)
|
||||
try:
|
||||
self._resolved[child.vol.type_name] = self._weak_resolve(SymbolType.TYPE,
|
||||
child.vol.type_name)
|
||||
@@ -167,7 +167,7 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface, validity.ValidityRout
|
||||
# Traverse down any resolutions
|
||||
if type_name not in self._resolved:
|
||||
self._resolved[type_name] = self._weak_resolve(SymbolType.TYPE, type_name) # type: ignore
|
||||
self._recursive_resolve([self._resolved[type_name]])
|
||||
self._iterative_resolve([type_name])
|
||||
if isinstance(self._resolved[type_name], objects.templates.ReferenceTemplate):
|
||||
raise exceptions.SymbolError("Unresolvable symbol requested: {}".format(type_name))
|
||||
return self._resolved[type_name]
|
||||
@@ -175,8 +175,16 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface, validity.ValidityRout
|
||||
def get_symbol(self, symbol_name: str) -> interfaces.symbols.Symbol:
|
||||
"""Look-up a symbol name across all the contained symbol spaces"""
|
||||
retval = self._weak_resolve(SymbolType.SYMBOL, symbol_name)
|
||||
if isinstance(retval.type, templates.ObjectTemplate):
|
||||
self._recursive_resolve([retval.type])
|
||||
if symbol_name not in self._resolved_symbols and retval.type is not None:
|
||||
# Stash the old resolved type if it exists
|
||||
old_resolved = self._resolved.get(symbol_name, None)
|
||||
try:
|
||||
self._resolved[symbol_name] = retval.type
|
||||
self._iterative_resolve([symbol_name])
|
||||
self._resolved_symbols.add(symbol_name)
|
||||
finally:
|
||||
if old_resolved is not None:
|
||||
self._resolved[symbol_name] = old_resolved
|
||||
if not isinstance(retval, interfaces.symbols.Symbol):
|
||||
raise exceptions.SymbolError("Unresolvable Symbol: {}".format(symbol_name))
|
||||
return retval
|
||||
|
||||
Reference in New Issue
Block a user