import copy from volatility.framework import constants, interfaces, objects class NativeTable(interfaces.symbols.NativeTableInterface): """Symbol List that handles Native types""" def __init__(self, name, native_dictionary): super().__init__(name, self) self._native_dictionary = copy.deepcopy(native_dictionary) self._overrides = {} for native_type in self._native_dictionary: native_class, _native_struct = self._native_dictionary[native_type] self._overrides[native_type] = native_class # Create this once early, because it may get used a lot self._types = set(self._native_dictionary).union( {'enum', 'array', 'bitfield', 'void', 'pointer', 'string', 'bytes', 'function'}) def get_type_class(self, name): ntype, fmt = native_types.get(name, (objects.Integer, '')) return ntype @property def types(self): """Returns an iterator of the symbol type names""" return self._types def get_type(self, type_name): """Resolves a symbol name into an object template symbol_space is used to resolve any subtype symbols if they don't exist in this list """ # NOTE: These need updating whenever the object init signatures change prefix = "" if constants.BANG in type_name: name_split = type_name.split(constants.BANG) if len(name_split) > 2: raise ValueError("SymbolName cannot contain multiple {} separators".format(constants.BANG)) table_name, type_name = name_split prefix = table_name + constants.BANG additional = {} obj = None if type_name == 'void' or type_name == 'function': obj = objects.Void elif type_name == 'array': obj = objects.Array additional = {"count": 0, "subtype": self.get_type('void')} elif type_name == 'enum': obj = objects.Enumeration additional = {"base_type": self.get_type('int'), "choices": {}} elif type_name == 'bitfield': obj = objects.BitField additional = {"start_bit": 0, "end_bit": 0, "base_type": self.get_type('int')} elif type_name == 'string': obj = objects.String additional = {"max_length": 0} elif type_name == 'bytes': obj = objects.Bytes additional = {"length": 0} if obj is not None: return objects.templates.ObjectTemplate(obj, type_name = prefix + type_name, **additional) _native_type, native_format = self._native_dictionary[type_name] if type_name == 'pointer': additional = {'subtype': self.get_type('void')} return objects.templates.ObjectTemplate(self.get_type_class(type_name), # pylint: disable=W0142 type_name = prefix + type_name, struct_format = native_format, **additional) std_ctypes = {'int': (objects.Integer, 'H'), 'short': (objects.Integer, '