mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-12 04:37:38 +02:00
exceptions: SymbolErrors now contain specific information
This commit is contained in:
@@ -288,35 +288,36 @@ class CommandLine(interfaces.plugins.FileConsumerInterface):
|
||||
if isinstance(excp, exceptions.InvalidAddressException):
|
||||
if isinstance(excp, exceptions.SwappedInvalidAddressException):
|
||||
print("\nVolatility was unable to read a requested page from swap:\n"
|
||||
"{} in layer {}\n\n"
|
||||
"{} in layer {}: {}\n\n"
|
||||
"This is likely caused by:\n"
|
||||
"\tNo suitable swap file having been provided (locate and provide the correct swap file)\n"
|
||||
"\tAn intentionally invalid page (operating system protection)".format(
|
||||
hex(excp.invalid_address), excp.layer_name))
|
||||
hex(excp.invalid_address), excp.layer_name, excp))
|
||||
elif isinstance(excp, exceptions.PagedInvalidAddressException):
|
||||
print("\nVolatility was unable to read a requested page:\n"
|
||||
"{} in layer {}\n\n"
|
||||
"{} in layer {}: {}\n\n"
|
||||
"This could be caused by:\n"
|
||||
"\tMemory smear during acquisition (try re-acquiring if possible)\n"
|
||||
"\tAn intentionally invalid page lookup (operating system protection)\n"
|
||||
"\tA bug in the plugin/volatility (re-run with -vvv and file a bug)".format(
|
||||
hex(excp.invalid_address), excp.layer_name))
|
||||
hex(excp.invalid_address), excp.layer_name, excp))
|
||||
else:
|
||||
print("\nVolatility was unable to read a requested page:\n"
|
||||
"{} in layer {}\n\n"
|
||||
"{} in layer {}: {}\n\n"
|
||||
"This could be caused by:\n"
|
||||
"\tThe base memory file being incomplete (try re-acquiring if possible)\n"
|
||||
"\tMemory smear during acquisition (try re-acquiring if possible)\n"
|
||||
"\tAn intentionally invalid page lookup (operating system protection)\n"
|
||||
"\tA bug in the plugin/volatility (re-run with -vvv and file a bug)".format(
|
||||
hex(excp.invalid_address), excp.layer_name))
|
||||
hex(excp.invalid_address), excp.layer_name, excp))
|
||||
elif isinstance(excp, exceptions.SymbolError):
|
||||
print("\nVolatility experienced a symbol-related issue:\n"
|
||||
"{}\n\n"
|
||||
"{}{}{}: {}\n\n"
|
||||
"This is likely caused by:\n"
|
||||
"\tAn invalid symbol table\n"
|
||||
"\tA plugin requesting a bad symbol\n"
|
||||
"\tA plugin requesting a symbol from the wrong table\n".format(excp))
|
||||
"\tA plugin requesting a symbol from the wrong table\n".format(excp.table_name, constants.BANG,
|
||||
excp.symbol_name, excp))
|
||||
elif isinstance(excp, exceptions.SymbolSpaceError):
|
||||
print("\nVolatility experienced an issue related to a symbol table:\n "
|
||||
"{}\n\n"
|
||||
|
||||
@@ -8,7 +8,7 @@ space or symbol tables, and by layers when an address is invalid. The
|
||||
:class:`PagedInvalidAddressException` contains information about the
|
||||
size of the invalid page.
|
||||
"""
|
||||
from typing import Dict
|
||||
from typing import Dict, Optional
|
||||
|
||||
from volatility.framework import interfaces
|
||||
|
||||
@@ -30,6 +30,11 @@ class PluginRequirementException(VolatilityException):
|
||||
class SymbolError(VolatilityException):
|
||||
"""Thrown when a symbol lookup has failed."""
|
||||
|
||||
def __init__(self, symbol_name: Optional[str], table_name: Optional[str], *args) -> None:
|
||||
super().__init__(*args)
|
||||
self.symbol_name = symbol_name
|
||||
self.table_name = table_name
|
||||
|
||||
|
||||
class LayerException(VolatilityException):
|
||||
"""Thrown when an error occurs dealing with memory and layers."""
|
||||
|
||||
@@ -295,14 +295,14 @@ class NativeTableInterface(BaseSymbolTableInterface):
|
||||
"""Class to distinguish NativeSymbolLists from other symbol lists."""
|
||||
|
||||
def get_symbol(self, name: str) -> SymbolInterface:
|
||||
raise exceptions.SymbolError("NativeTables never hold symbols")
|
||||
raise exceptions.SymbolError(name, self.name, "NativeTables never hold symbols")
|
||||
|
||||
@property
|
||||
def symbols(self) -> Iterable[str]:
|
||||
return []
|
||||
|
||||
def get_enumeration(self, name: str) -> objects.Template:
|
||||
raise exceptions.SymbolError("NativeTables never hold enumerations")
|
||||
raise exceptions.SymbolError(name, self.name, "NativeTables never hold enumerations")
|
||||
|
||||
@property
|
||||
def enumerations(self) -> Iterable[str]:
|
||||
|
||||
@@ -5,7 +5,7 @@ import functools
|
||||
import logging
|
||||
from typing import Any, ClassVar, Dict, List, Type
|
||||
|
||||
from volatility.framework import interfaces, exceptions
|
||||
from volatility.framework import interfaces, exceptions, constants
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
@@ -87,8 +87,14 @@ class ReferenceTemplate(interfaces.objects.Template):
|
||||
"""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 exceptions.SymbolError("Template contains no information about its structure: {}".format(
|
||||
self.vol.type_name))
|
||||
type_name = self.vol.type_name.split(constants.BANG)
|
||||
table_name = None
|
||||
if len(type_name) == 2:
|
||||
table_name = type_name[0]
|
||||
symbol_name = type_name[-1]
|
||||
raise exceptions.SymbolError(
|
||||
symbol_name, table_name,
|
||||
"Template contains no information about its structure: {}".format(self.vol.type_name))
|
||||
|
||||
size = property(_unresolved) # type: ClassVar[Any]
|
||||
replace_child = _unresolved # type: ClassVar[Any]
|
||||
|
||||
@@ -43,11 +43,8 @@ class VirtMap(interfaces.plugins.PluginInterface):
|
||||
raise
|
||||
|
||||
result = {} # type: Dict[str, List[Tuple[int, int]]]
|
||||
try:
|
||||
system_va_type = module.get_enumeration('_MI_SYSTEM_VA_TYPE')
|
||||
large_page_size = (layer.page_size ** 2) // module.get_type("_MMPTE").size
|
||||
except exceptions.SymbolError:
|
||||
raise exceptions.SymbolError("Required structures not found")
|
||||
system_va_type = module.get_enumeration('_MI_SYSTEM_VA_TYPE')
|
||||
large_page_size = (layer.page_size ** 2) // module.get_type("_MMPTE").size
|
||||
|
||||
if module.has_symbol('MiVisibleState'):
|
||||
symbol = module.get_symbol('MiVisibleState')
|
||||
@@ -67,7 +64,7 @@ class VirtMap(interfaces.plugins.PluginInterface):
|
||||
result = cls._enumerate_system_va_type(large_page_size, system_range_start, module,
|
||||
visible_state.SystemVaType)
|
||||
else:
|
||||
raise exceptions.SymbolError("Required structures not found")
|
||||
raise exceptions.SymbolError(None, module.name, "Required structures not found")
|
||||
elif module.has_symbol('MiSystemVaType'):
|
||||
system_range_start = module.object(object_type = "pointer",
|
||||
offset = module.get_symbol("MmSystemRangeStart").address)
|
||||
@@ -80,7 +77,7 @@ class VirtMap(interfaces.plugins.PluginInterface):
|
||||
|
||||
result = cls._enumerate_system_va_type(large_page_size, system_range_start, module, type_array)
|
||||
else:
|
||||
raise exceptions.SymbolError("Required structures not found")
|
||||
raise exceptions.SymbolError(None, module.name, "Required structures not found")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -127,8 +127,9 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface):
|
||||
try:
|
||||
return getattr(self._dict[table_name], get_function)(component_name)
|
||||
except KeyError as e:
|
||||
raise exceptions.SymbolError('Type {} references missing Type/Symbol/Enum: {}'.format(name, e))
|
||||
raise exceptions.SymbolError("Malformed name: {}".format(name))
|
||||
raise exceptions.SymbolError(component_name, table_name,
|
||||
'Type {} references missing Type/Symbol/Enum: {}'.format(name, e))
|
||||
raise exceptions.SymbolError(name, None, "Malformed name: {}".format(name))
|
||||
|
||||
def _iterative_resolve(self, traverse_list):
|
||||
"""Iteratively resolves a type, populating linked child
|
||||
@@ -169,7 +170,11 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface):
|
||||
self._resolved[type_name] = self._weak_resolve(SymbolType.TYPE, type_name) # type: ignore
|
||||
self._iterative_resolve([type_name])
|
||||
if isinstance(self._resolved[type_name], objects.templates.ReferenceTemplate):
|
||||
raise exceptions.SymbolError("Unresolvable symbol requested: {}".format(type_name))
|
||||
table_name = None
|
||||
index = type_name.find(constants.BANG)
|
||||
if index > 0:
|
||||
table_name, type_name = type_name[:index], type_name[index + 1:]
|
||||
raise exceptions.SymbolError(type_name, table_name, "Unresolvable symbol requested: {}".format(type_name))
|
||||
return self._resolved[type_name]
|
||||
|
||||
def get_symbol(self, symbol_name: str) -> interfaces.symbols.SymbolInterface:
|
||||
@@ -189,7 +194,11 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface):
|
||||
if old_resolved is not None:
|
||||
self._resolved_symbols[symbol_name] = old_resolved
|
||||
if not isinstance(retval, interfaces.symbols.SymbolInterface):
|
||||
raise exceptions.SymbolError("Unresolvable Symbol: {}".format(symbol_name))
|
||||
table_name = None
|
||||
index = symbol_name.find(constants.BANG)
|
||||
if index > 0:
|
||||
table_name, symbol_name = symbol_name[:index], symbol_name[index + 1:]
|
||||
raise exceptions.SymbolError(symbol_name, table_name, "Unresolvable Symbol: {}".format(symbol_name))
|
||||
return retval
|
||||
|
||||
def get_enumeration(self, enum_name: str) -> interfaces.objects.Template:
|
||||
@@ -197,7 +206,11 @@ class SymbolSpace(interfaces.symbols.SymbolSpaceInterface):
|
||||
table."""
|
||||
retval = self._weak_resolve(SymbolType.ENUM, enum_name)
|
||||
if not isinstance(retval, interfaces.objects.Template):
|
||||
raise exceptions.SymbolError("Unresolvable Enumeration: {}".format(enum_name))
|
||||
table_name = None
|
||||
index = enum_name.find(constants.BANG)
|
||||
if index > 0:
|
||||
table_name, enum_name = enum_name[:index], enum_name[index + 1:]
|
||||
raise exceptions.SymbolError(enum_name, table_name, "Unresolvable Enumeration: {}".format(enum_name))
|
||||
return retval
|
||||
|
||||
def _membership(self, member_type: SymbolType, name: str) -> bool:
|
||||
|
||||
@@ -312,7 +312,7 @@ class Version1Format(ISFormatTable):
|
||||
return self._symbol_cache[name]
|
||||
symbol = self._json_object['symbols'].get(name, None)
|
||||
if not symbol:
|
||||
raise exceptions.SymbolError("Unknown symbol: {}".format(name))
|
||||
raise exceptions.SymbolError(name, self.name, "Unknown symbol: {}".format(name))
|
||||
self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name, address = symbol['address'])
|
||||
return self._symbol_cache[name]
|
||||
|
||||
@@ -402,10 +402,12 @@ class Version1Format(ISFormatTable):
|
||||
def get_enumeration(self, enum_name: str) -> interfaces.objects.Template:
|
||||
"""Resolves an individual enumeration."""
|
||||
if constants.BANG in enum_name:
|
||||
raise exceptions.SymbolError("Enumeration for a different table requested: {}".format(enum_name))
|
||||
raise exceptions.SymbolError(enum_name, self.name,
|
||||
"Enumeration for a different table requested: {}".format(enum_name))
|
||||
if enum_name not in self._json_object['enums']:
|
||||
# Fall back to the natives table
|
||||
raise exceptions.SymbolError("Enumeration not found in {} table: {}".format(self.name, enum_name))
|
||||
raise exceptions.SymbolError(enum_name, self.name,
|
||||
"Enumeration not found in {} table: {}".format(self.name, enum_name))
|
||||
curdict = self._json_object['enums'][enum_name]
|
||||
base_type = self.natives.get_type(curdict['base'])
|
||||
# The size isn't actually used, the base-type defines it.
|
||||
@@ -417,7 +419,13 @@ class Version1Format(ISFormatTable):
|
||||
def get_type(self, type_name: str) -> interfaces.objects.Template:
|
||||
"""Resolves an individual symbol."""
|
||||
if constants.BANG in type_name:
|
||||
raise exceptions.SymbolError("Symbol for a different table requested: {}".format(type_name))
|
||||
table_name = None
|
||||
index = type_name.find(constants.BANG)
|
||||
if index > 0:
|
||||
table_name, type_name = type_name[:index], type_name[index + 1:]
|
||||
raise exceptions.SymbolError(
|
||||
type_name, table_name,
|
||||
"Symbol for a different table requested: {}".format(table_name + constants.BANG + type_name))
|
||||
if type_name not in self._json_object['user_types']:
|
||||
# Fall back to the natives table
|
||||
return self.natives.get_type(self.name + constants.BANG + type_name)
|
||||
@@ -463,13 +471,19 @@ class Version2Format(Version1Format):
|
||||
def get_type(self, type_name: str) -> interfaces.objects.Template:
|
||||
"""Resolves an individual symbol."""
|
||||
if constants.BANG in type_name:
|
||||
raise exceptions.SymbolError("Symbol for a different table requested: {}".format(type_name))
|
||||
table_name = None
|
||||
index = type_name.find(constants.BANG)
|
||||
if index > 0:
|
||||
table_name, type_name = type_name[:index], type_name[index + 1:]
|
||||
raise exceptions.SymbolError(
|
||||
type_name, table_name,
|
||||
"Symbol for a different table requested: {}".format(table_name + constants.BANG + type_name))
|
||||
if type_name not in self._json_object['user_types']:
|
||||
# Fall back to the natives table
|
||||
if type_name in self.natives.types:
|
||||
return self.natives.get_type(self.name + constants.BANG + type_name)
|
||||
else:
|
||||
raise exceptions.SymbolError("Unknown symbol: {}".format(type_name))
|
||||
raise exceptions.SymbolError(type_name, self.name, "Unknown symbol: {}".format(type_name))
|
||||
curdict = self._json_object['user_types'][type_name]
|
||||
members = {}
|
||||
for member_name in curdict['fields']:
|
||||
@@ -497,7 +511,7 @@ class Version3Format(Version2Format):
|
||||
return self._symbol_cache[name]
|
||||
symbol = self._json_object['symbols'].get(name, None)
|
||||
if not symbol:
|
||||
raise exceptions.SymbolError("Unknown symbol: {}".format(name))
|
||||
raise exceptions.SymbolError(name, self.name, "Unknown symbol: {}".format(name))
|
||||
symbol_type = None
|
||||
if 'type' in symbol:
|
||||
symbol_type = self._interdict_to_template(symbol['type'])
|
||||
@@ -549,7 +563,7 @@ class Version5Format(Version4Format):
|
||||
return self._symbol_cache[name]
|
||||
symbol = self._json_object['symbols'].get(name, None)
|
||||
if not symbol:
|
||||
raise exceptions.SymbolError("Unknown symbol: {}".format(name))
|
||||
raise exceptions.SymbolError(name, self.name, "Unknown symbol: {}".format(name))
|
||||
symbol_type = None
|
||||
if 'type' in symbol:
|
||||
symbol_type = self._interdict_to_template(symbol['type'])
|
||||
|
||||
Reference in New Issue
Block a user