diff --git a/volatility/framework/automagic/symbol_finder.py b/volatility/framework/automagic/symbol_finder.py index d2eeea3a9..44c2eb64d 100644 --- a/volatility/framework/automagic/symbol_finder.py +++ b/volatility/framework/automagic/symbol_finder.py @@ -5,7 +5,7 @@ import logging from typing import Any, Iterable, List, Tuple, Type, Optional, Callable -from volatility.framework import interfaces, constants, layers, symbols +from volatility.framework import interfaces, constants, layers, exceptions from volatility.framework.automagic import symbol_cache from volatility.framework.configuration import requirements from volatility.framework.layers import scanners @@ -107,12 +107,21 @@ class SymbolFinder(interfaces.automagic.AutomagicInterface): path_join = interfaces.configuration.path_join context.config[path_join(config_path, requirement.name, "class")] = clazz context.config[path_join(config_path, requirement.name, "isf_url")] = isf_path + + # Set a default symbol_shift when attempt to determine it, + # so we can create the symbols which are used in finding the aslr_shift anyway + if not context.config.get(path_join(config_path, requirement.name, "symbol_shift"), None): + # Don't overwrite it if it's already been set, it will be manually refound if not present + context.config[path_join(config_path, requirement.name, "symbol_shift")] = 0 # Construct the appropriate symbol table requirement.construct(context, config_path) - # Apply the ASLR masking - if self.find_aslr: - unmasked_symbol_table_name = context.config[path_join(config_path, requirement.name)] + # Apply the ASLR masking (only if we're not already shifted) + if self.find_aslr and not context.config.get(path_join(config_path, requirement.name, "symbol_shift"), + None): + unmasked_symbol_table_name = context.config.get(path_join(config_path, requirement.name), None) + if not unmasked_symbol_table_name: + raise exceptions.SymbolSpaceError("Symbol table could not be constructed") if not isinstance(layer, layers.intel.Intel): raise TypeError("Layer name {} is not an intel space") aslr_shift = self.find_aslr(context, unmasked_symbol_table_name, layer.config['memory_layer']) diff --git a/volatility/framework/configuration/requirements.py b/volatility/framework/configuration/requirements.py index 5661e9bc4..f93c7469a 100644 --- a/volatility/framework/configuration/requirements.py +++ b/volatility/framework/configuration/requirements.py @@ -326,16 +326,22 @@ class SymbolTableRequirement(interfaces.configuration.ConstructableRequirementIn provided context.""" config_path = interfaces.configuration.path_join(config_path, self.name) value = self.config_value(context, config_path, None) - if not isinstance(value, str): + if not isinstance(value, str) and value is not None: vollog.log(constants.LOGLEVEL_V, "TypeError - SymbolTableRequirement only accepts string labels: {}".format(repr(value))) return {config_path: self} - if value not in context.symbol_space: - # This is an expected situation, so return False rather than raise + if value and value in context.symbol_space: + # This is an expected situation, so return rather than raise + return {} + elif value: vollog.log(constants.LOGLEVEL_V, "IndexError - Value not present in the symbol space: {}".format(value or "")) - return {config_path: self} - return {} + + ### NOTE: This validate method has side effects (the dependencies can change)!!! + + self._validate_class(context, interfaces.configuration.parent_path(config_path)) + vollog.log(constants.LOGLEVEL_V, "Symbol table requirement not yet fulfilled: {}".format(config_path)) + return {config_path: self} def construct(self, context: interfaces.context.ContextInterface, config_path: str) -> None: """Constructs the symbol space within the context based on the diff --git a/volatility/framework/symbols/intermed.py b/volatility/framework/symbols/intermed.py index 4dd4a51ae..87a7c00eb 100644 --- a/volatility/framework/symbols/intermed.py +++ b/volatility/framework/symbols/intermed.py @@ -245,8 +245,7 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface): return super().get_requirements() + [ requirements.StringRequirement( "isf_url", description = "JSON file containing the symbols encoded in the Intermediate Symbol Format"), - requirements.IntRequirement( - name = 'symbol_shift', description = 'Symbol Shift', optional = True, default = 0) + requirements.IntRequirement(name = 'symbol_shift', description = 'Symbol Shift', optional = False) ]