Symbols: Apply symbol_masking option to IntermediateSymbolTables

This commit is contained in:
Mike Auty
2020-06-10 19:39:20 +01:00
committed by ikelos
parent 085ccc47e0
commit ede5ba07aa
3 changed files with 24 additions and 9 deletions
@@ -107,6 +107,7 @@ 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
context.config[path_join(config_path, requirement.name, "symbol_mask")] = layer.address_mask
# 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
+3 -1
View File
@@ -294,7 +294,9 @@ class SymbolTableInterface(BaseSymbolTableInterface, configuration.ConfigurableI
@classmethod
def get_requirements(cls) -> List[RequirementInterface]:
return super().get_requirements() + [
requirements.IntRequirement(name = 'symbol_shift', description = 'Symbol Shift', optional = False)
requirements.IntRequirement(name = 'symbol_shift', description = 'Symbol Shift', optional = False),
requirements.IntRequirement(
name = 'symbol_mask', description = 'Address mask for symbols', optional = True, default = 0),
]
+20 -8
View File
@@ -84,7 +84,8 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
table_mapping: Optional[Dict[str, str]] = None,
validate: bool = True,
class_types: Optional[Mapping[str, Type[interfaces.objects.ObjectInterface]]] = None,
symbol_shift: int = 0) -> None:
symbol_shift: int = 0,
symbol_mask: int = 0) -> None:
"""Instantiates a SymbolTable based on an IntermediateSymbolFormat JSON file. This is validated against the
appropriate schema. The validation can be disabled by passing validate = False, but this should almost never be
done.
@@ -98,12 +99,13 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
table_mapping: A dictionary linking names referenced in the file with symbol tables in the context
validate: Determines whether the ISF file will be validated against the appropriate schema
class_types: A dictionary of type names and classes that override StructType when they are instantiated
symbol_shift: An offset by which to alter all returned symbols for this table
symbol_mask: An address mask used for all returned symbol offsets from this table (a mask of 0 disables masking)
"""
# Check there are no obvious errors
# Open the file and test the version
self._isf_url = isf_url
self._versions = dict([(x.version, x) for x in class_subclasses(ISFormatTable)])
fp = volatility.framework.layers.resources.ResourceAccessor().open(self._isf_url)
fp = volatility.framework.layers.resources.ResourceAccessor().open(isf_url)
reader = codecs.getreader("utf-8")
json_object = json.load(reader(fp)) # type: ignore
fp.close()
@@ -127,6 +129,11 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
table_mapping = table_mapping,
class_types = class_types)
# Since we've been created with parameters, ensure our config is populated likewise
self.config['isf_url'] = isf_url
self.config['symbol_shift'] = symbol_shift
self.config['symbol_mask'] = symbol_mask
@staticmethod
def _closest_version(version: str, versions: Dict[Tuple[int, int, int], Type['ISFormatTable']]) \
-> Type['ISFormatTable']:
@@ -210,7 +217,8 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
native_types: Optional[interfaces.symbols.NativeTableInterface] = None,
table_mapping: Optional[Dict[str, str]] = None,
class_types: Optional[Mapping[str, Type[interfaces.objects.ObjectInterface]]] = None,
symbol_shift: int = 0) -> str:
symbol_shift: int = 0,
symbol_mask: int = 0) -> str:
"""Takes a context and loads an intermediate symbol table based on a
filename.
@@ -221,6 +229,8 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
filename: Basename of the file to find under the sub_path
native_types: Set of native types, defaults to native types read from the intermediate symbol format file
table_mapping: a dictionary of table names mentioned within the ISF file, and the tables within the context which they map to
symbol_shift: An offset by which to alter all returned symbols for this table
symbol_mask: An address mask used for all returned symbol offsets from this table (a mask of 0 disables masking)
Returns:
the name of the added symbol table
@@ -236,7 +246,8 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
native_types = native_types,
table_mapping = table_mapping,
class_types = class_types,
symbol_shift = symbol_shift)
symbol_shift = symbol_shift,
symbol_mask = symbol_mask)
context.symbol_space.append(table)
return table_name
@@ -245,7 +256,6 @@ 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 = False)
]
@@ -318,8 +328,10 @@ class Version1Format(ISFormatTable):
symbol = self._json_object['symbols'].get(name, None)
if not symbol:
raise exceptions.SymbolError(name, self.name, "Unknown symbol: {}".format(name))
self._symbol_cache[name] = interfaces.symbols.SymbolInterface(
name = name, address = symbol['address'] + self.config.get('symbol_shift', 0))
address = symbol['address'] + self.config.get('symbol_shift', 0)
if self.config.get('symbol_mask', 0):
address = address & self.config['symbol_mask']
self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name, address = address)
return self._symbol_cache[name]
@property