mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-09 19:27:39 +02:00
Make SymbolTable.symbols consistent with enumerations and types.
This commit is contained in:
@@ -163,15 +163,17 @@ class BaseSymbolTableInterface(validity.ValidityRoutines):
|
||||
|
||||
def get_symbols_by_type(self, type_name):
|
||||
"""Returns the name of all symbols in this table that have type matching type_name"""
|
||||
for symbol in self.symbols:
|
||||
for symbol_name in self.symbols:
|
||||
# This allows for searching with and without the table name (in case multiple tables contain
|
||||
# the same symbol name and we've not specifically been told which one)
|
||||
symbol = self.get_symbol(symbol_name)
|
||||
if symbol.type_name == type_name or (symbol.type_name.endswith(constants.BANG + type_name)):
|
||||
yield symbol.name
|
||||
|
||||
def get_symbols_by_location(self, offset):
|
||||
"""Returns the name of all symbols in this table that have type matching type_name"""
|
||||
sort_symbols = [(s.offset, s) for s in sorted(self.symbols, key = lambda x: x.offset)]
|
||||
"""Returns the name of all symbols in this table that live at a particular offset"""
|
||||
sort_symbols = [(s.offset, s) for s in
|
||||
sorted([self.get_symbol(sn) for sn in self.symbols], key = lambda x: x.offset)]
|
||||
result = bisect.bisect_left(sort_symbols, offset)
|
||||
if result == len(sort_symbols):
|
||||
raise StopIteration
|
||||
|
||||
@@ -166,7 +166,7 @@ class Version1Format(ISFormatTable):
|
||||
nt.name = name + "_natives"
|
||||
super().__init__(context, config_path, name, nt)
|
||||
self._overrides = {}
|
||||
self._symbol_cache = None
|
||||
self._symbol_cache = {}
|
||||
|
||||
def _get_natives(self):
|
||||
"""Determines the appropriate native_types to use from the JSON data"""
|
||||
@@ -197,24 +197,30 @@ class Version1Format(ISFormatTable):
|
||||
|
||||
def get_symbol(self, name):
|
||||
"""Returns the location offset given by the symbol name"""
|
||||
# TODO: Add the ability to add/remove/change symbols after creation
|
||||
# note that this should invalidate/update the cache
|
||||
if self._symbol_cache.get(name, None):
|
||||
return self._symbol_cache[name]
|
||||
symbol = self._json_object['symbols'].get(name, None)
|
||||
if not symbol:
|
||||
raise exceptions.SymbolError("Unknown symbol: {}".format(name))
|
||||
return interfaces.symbols.Symbol(name = name, address = symbol['address'])
|
||||
self._symbol_cache[name] = interfaces.symbols.Symbol(name = name, address = symbol['address'])
|
||||
return self._symbol_cache[name]
|
||||
|
||||
@property
|
||||
def symbols(self):
|
||||
if not self._symbol_cache:
|
||||
self._symbol_cache = [self.get_symbol(x) for x in self._json_object['symbols']]
|
||||
return self._symbol_cache
|
||||
|
||||
# TODO: Add the ability to add/remove/change symbols after creation, note that this should invalidate the cache
|
||||
return self._json_object.get('symbols', {}).keys()
|
||||
|
||||
@property
|
||||
def enumerations(self):
|
||||
"""Returns an iterator of the available enumerations"""
|
||||
return self._json_object.get('enums', {}).keys()
|
||||
|
||||
@property
|
||||
def types(self):
|
||||
"""Returns an iterator of the symbol names"""
|
||||
return list(self._json_object.get('user_types', {}).keys()) + list(self.natives.types)
|
||||
|
||||
def get_type_class(self, name):
|
||||
return self._overrides.get(name, objects.Struct)
|
||||
|
||||
@@ -227,11 +233,6 @@ class Version1Format(ISFormatTable):
|
||||
if name in self._overrides:
|
||||
del self._overrides[name]
|
||||
|
||||
@property
|
||||
def types(self):
|
||||
"""Returns an iterator of the symbol names"""
|
||||
return list(self._json_object.get('user_types', {}).keys()) + list(self.natives.types)
|
||||
|
||||
def _interdict_to_template(self, dictionary):
|
||||
"""Converts an intermediate format dict into an object template"""
|
||||
if not dictionary:
|
||||
@@ -366,14 +367,18 @@ class Version3Format(Version2Format):
|
||||
version = (current - age, age, revision)
|
||||
|
||||
def get_symbol(self, name):
|
||||
"""Returns the location offset given by the symbol name"""
|
||||
"""Returns the symbol given by the symbol name"""
|
||||
if self._symbol_cache.get(name, None):
|
||||
return self._symbol_cache[name]
|
||||
symbol = self._json_object['symbols'].get(name, None)
|
||||
if not symbol:
|
||||
raise exceptions.SymbolError("Unknown symbol: {}".format(name))
|
||||
symbol_type = None
|
||||
if 'type' in symbol:
|
||||
symbol_type = self._interdict_to_template(symbol['type'])
|
||||
return interfaces.symbols.Symbol(name = name, address = symbol['address'], type = symbol_type)
|
||||
self._symbol_cache[name] = interfaces.symbols.Symbol(name = name, address = symbol['address'],
|
||||
type = symbol_type)
|
||||
return self._symbol_cache[name]
|
||||
|
||||
|
||||
class Version4Format(Version3Format):
|
||||
@@ -422,7 +427,9 @@ class Version5Format(Version4Format):
|
||||
version = (current - age, age, revision)
|
||||
|
||||
def get_symbol(self, name):
|
||||
"""Returns the location offset given by the symbol name"""
|
||||
"""Returns the symbol given by the symbol name"""
|
||||
if self._symbol_cache.get(name, None):
|
||||
return self._symbol_cache[name]
|
||||
symbol = self._json_object['symbols'].get(name, None)
|
||||
if not symbol:
|
||||
raise exceptions.SymbolError("Unknown symbol: {}".format(name))
|
||||
@@ -432,5 +439,7 @@ class Version5Format(Version4Format):
|
||||
symbol_constant_data = None
|
||||
if 'constant_data' in symbol:
|
||||
symbol_constant_data = base64.b64decode(symbol.get('constant_data'))
|
||||
return interfaces.symbols.Symbol(name = name, address = symbol['address'], type = symbol_type,
|
||||
constant_data = symbol_constant_data)
|
||||
self._symbol_cache[name] = interfaces.symbols.Symbol(name = name, address = symbol['address'],
|
||||
type = symbol_type,
|
||||
constant_data = symbol_constant_data)
|
||||
return self._symbol_cache[name]
|
||||
|
||||
Reference in New Issue
Block a user