diff --git a/volatility/framework/interfaces/renderers.py b/volatility/framework/interfaces/renderers.py index 810f351b6..3d4f66b96 100644 --- a/volatility/framework/interfaces/renderers.py +++ b/volatility/framework/interfaces/renderers.py @@ -45,7 +45,7 @@ class TreeNode(collections.Sequence, metaclass = ABCMeta): @property @abstractmethod - def values(self) -> typing.Iterable['SimpleTypes']: + def values(self) -> typing.Iterable['BaseTypes']: """Returns the list of values from the particular node, based on column.index""" @property @@ -79,17 +79,32 @@ class BaseAbsentValue(object): """Class that represents values which are not present for some reason""" -# We don't class these off a shared base, because the SimpleTypes must only +class Disassembly(object): + """A class to indicate that the bytes provided should be disassembled (based on the architecture)""" + possible_architectures = ['intel', 'intel64', 'arm', 'arm64'] + + def __init__(self, data: bytes, offset: int = 0, architecture: str = 'intel64'): + self.data = data + self.architecture = None + if architecture in self.possible_architectures: + self.architecture = architecture + if not isinstance(offset, int): + raise TypeError("Offset must be an integer type") + self.offset = offset + + +# We don't class these off a shared base, because the BaseTypes must only # contain the types that the validator will accept (which would not include the base) _Type = typing.TypeVar("_Type") ColumnsType = typing.List[typing.Tuple[str, typing.Type]] -SimpleTypes = typing.Union[typing.Type[int], - typing.Type[str], - typing.Type[float], - typing.Type[bytes], - typing.Type[datetime.datetime], - typing.Type[BaseAbsentValue]] +BaseTypes = typing.Union[typing.Type[int], + typing.Type[str], + typing.Type[float], + typing.Type[bytes], + typing.Type[datetime.datetime], + typing.Type[BaseAbsentValue], + typing.Type[Disassembly]] VisitorSignature = typing.Callable[[TreeNode, _Type], _Type] @@ -106,7 +121,7 @@ class TreeGrid(object, metaclass = ABCMeta): and to create cycles. """ - simple_types = (int, str, float, bytes, datetime.datetime) # type: typing.ClassVar[typing.Tuple] + base_types = (int, str, float, bytes, datetime.datetime, Disassembly) # type: typing.ClassVar[typing.Tuple] def __init__(self, columns: ColumnsType, generator: typing.Generator) -> None: """Constructs a TreeGrid object using a specific set of columns @@ -149,7 +164,7 @@ class TreeGrid(object, metaclass = ABCMeta): """Returns the subnodes of a particular node in order""" @abstractmethod - def values(self, node: TreeNode) -> typing.Tuple[SimpleTypes, ...]: + def values(self, node: TreeNode) -> typing.Tuple[BaseTypes, ...]: """Returns the values for a particular node The values returned are mutable, diff --git a/volatility/framework/renderers/__init__.py b/volatility/framework/renderers/__init__.py index 4a10d4985..5783d9f74 100644 --- a/volatility/framework/renderers/__init__.py +++ b/volatility/framework/renderers/__init__.py @@ -28,7 +28,7 @@ class TreeNode(interfaces.renderers.TreeNode): path: str, treegrid: 'TreeGrid', parent: typing.Optional['TreeNode'], - values: typing.List[interfaces.renderers.SimpleTypes]) -> None: + values: typing.List[interfaces.renderers.BaseTypes]) -> None: if not isinstance(treegrid, TreeGrid): raise TypeError("Treegrid must be an instance of TreeGrid") self._treegrid = treegrid @@ -46,7 +46,7 @@ class TreeNode(interfaces.renderers.TreeNode): def __len__(self) -> int: return len(self._treegrid.children(self)) - def _validate_values(self, values: typing.List[interfaces.renderers.SimpleTypes]) -> None: + def _validate_values(self, values: typing.List[interfaces.renderers.BaseTypes]) -> None: """A function for raising exceptions if a given set of values is invalid according to the column properties.""" if not (isinstance(values, collections.Sequence) and len(values) == len(self._treegrid.columns)): raise TypeError( @@ -66,7 +66,7 @@ class TreeNode(interfaces.renderers.TreeNode): # tznaive = val.tzinfo is None or val.tzinfo.utcoffset(val) is None @property - def values(self) -> typing.Iterable[interfaces.renderers.SimpleTypes]: + def values(self) -> typing.Iterable[interfaces.renderers.BaseTypes]: """Returns the list of values from the particular node, based on column.index""" return self._values @@ -118,7 +118,7 @@ class TreeGrid(interfaces.renderers.TreeGrid): path_sep = "|" def __init__(self, - columns: typing.List[typing.Tuple[str, interfaces.renderers.SimpleTypes]], + columns: typing.List[typing.Tuple[str, interfaces.renderers.BaseTypes]], generator: typing.Optional[typing.Iterable[typing.Tuple[int, typing.Tuple]]]) -> None: """Constructs a TreeGrid object using a specific set of columns @@ -136,7 +136,7 @@ class TreeGrid(interfaces.renderers.TreeGrid): if len(columns) < 1: raise ValueError("Columns must be a list containing at least one column") for (name, column_type) in columns: - is_simple_type = issubclass(column_type, self.simple_types) + is_simple_type = issubclass(column_type, self.base_types) if not is_simple_type: raise TypeError( "Column {}'s type is not a simple type: {}".format(name, column_type.__class__.__name__))