From 56759420500a05abc6c0ab85bdbdb51c855d73d6 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Sat, 8 Jul 2017 21:50:25 +0100 Subject: [PATCH] Add in symbol constant_data and bump the schema to 0.4.1. Special thanks to @npetroni for having to suffer a very long discussion with me about my need for things to have particular names because I don't know the field very well. 5:S Sorry! 5:) --- volatility/framework/interfaces/symbols.py | 13 ++++++++++-- volatility/framework/symbols/intermed.py | 23 ++++++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/volatility/framework/interfaces/symbols.py b/volatility/framework/interfaces/symbols.py index f68e195c0..8e3211603 100644 --- a/volatility/framework/interfaces/symbols.py +++ b/volatility/framework/interfaces/symbols.py @@ -11,17 +11,22 @@ from volatility.framework.interfaces import configuration, objects class Symbol(validity.ValidityRoutines): """Contains information about a named location in a program's memory""" - def __init__(self, name, address, type = None): + def __init__(self, name, address, type = None, constant_data = None): self._name = self._check_type(name, str) if constants.BANG in self._name: raise ValueError("Symbol names cannot contain the symbol differentiator ({})".format(constants.BANG)) + + # Scope can be added at a later date self._location = None self._address = self._check_type(address, int) + self._type = None if type is not None: self._type = self._check_type(type, objects.Template) - # Scope and location can be added at a later date + self._constant_data = None + if constant_data is not None: + self._constant_data = self._check_type(bytes, constant_data) @property def name(self): @@ -38,6 +43,10 @@ class Symbol(validity.ValidityRoutines): """Returns the relative address of the symbol within the compilation unit""" return self._address + @property + def constant_data(self): + return self._constant_data + class SymbolSpaceInterface(collections.abc.Mapping): """An interface for the container that holds all the symbol-containing tables for use within a context""" diff --git a/volatility/framework/symbols/intermed.py b/volatility/framework/symbols/intermed.py index de7c26acf..4ec089166 100644 --- a/volatility/framework/symbols/intermed.py +++ b/volatility/framework/symbols/intermed.py @@ -109,12 +109,12 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface): def _closest_version(self, version, versions): """Determines the highest suitable handler for specified version format - An interface version such as Current.Age.Revision means that (Current - Age) of the provider must be equal to that of the + An interface version such as (Current-Age).Age.Revision means that (Current - Age) of the provider must be equal to that of the consumer, and the provider (the JSON in this instance) must have a greater age (indicating that only additive changes have been made) than the consumer (in this case, the file reader). """ supported, age, revision = [int(x) for x in version.split(".")] - supported_versions = [x for x in versions.keys() if x[0] == (supported - age) and x[1] >= age] + supported_versions = [x for x in versions.keys() if x[0] == supported and x[1] >= age] if not supported_versions: raise ValueError( "No Intermediate Format interface versions support file interface version: {}".format(version)) @@ -396,3 +396,22 @@ class Version4Format(Version3Format): object_type = objects.Pointer native_dict[base_type] = (object_type, format_str) return native.NativeTable(name = "native", native_dictionary = native_dict) + + +class Version5Format(Version4Format): + """Class for storing intermediate debugging data as objects and classes""" + current = 5 + revision = 0 + age = 1 + version = (current - age, age, revision) + + def get_symbol(self, name): + """Returns the location offset given by the symbol name""" + symbol = self._json_object['symbols'].get(name, None) + if not symbol: + raise KeyError("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, + constant_data = symbol.get('constant_data', None))