From aed87346cdd362fb59fce772cbd62b0dded51bf5 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Thu, 23 Jun 2022 09:23:31 +0100 Subject: [PATCH] Core: Add support to templates to get child templates --- volatility3/framework/constants/__init__.py | 2 +- volatility3/framework/interfaces/objects.py | 11 +++++++++++ volatility3/framework/objects/__init__.py | 17 +++++++++++++++++ volatility3/framework/objects/templates.py | 7 +++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index 472a743e6..f08819f29 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -39,7 +39,7 @@ BANG = "!" # We use the SemVer 2.0.0 versioning scheme VERSION_MAJOR = 2 # Number of releases of the library with a breaking change -VERSION_MINOR = 2 # Number of changes that only add to the interface +VERSION_MINOR = 3 # Number of changes that only add to the interface VERSION_PATCH = 0 # Number of changes that do not change the interface VERSION_SUFFIX = "" diff --git a/volatility3/framework/interfaces/objects.py b/volatility3/framework/interfaces/objects.py index 2240c58c9..3cc23e759 100644 --- a/volatility3/framework/interfaces/objects.py +++ b/volatility3/framework/interfaces/objects.py @@ -241,6 +241,13 @@ class ObjectInterface(metaclass = abc.ABCMeta): the child member.""" raise KeyError(f"Template does not contain any children: {template.vol.type_name}") + @classmethod + @abc.abstractmethod + def child_template(cls, template: 'Template', child: str) -> interfaces.objects.Template: + """Returns the template of the child member from the parent.""" + raise KeyError(f"Template does not contain any children: {template.vol.type_name}") + + @classmethod @abc.abstractmethod def has_member(cls, template: 'Template', member_name: str) -> bool: @@ -305,6 +312,10 @@ class Template: """Returns the relative offset of the `child` member from its parent offset.""" + @abc.abstractmethod + def child_template(self, child: str) -> interfaces.objects.Template: + """Returns the `child` member template from its parent.""" + @abc.abstractmethod def replace_child(self, old_child: 'Template', new_child: 'Template') -> None: """Replaces `old_child` with `new_child` in the list of children.""" diff --git a/volatility3/framework/objects/__init__.py b/volatility3/framework/objects/__init__.py index e0f927ec9..feb49a089 100644 --- a/volatility3/framework/objects/__init__.py +++ b/volatility3/framework/objects/__init__.py @@ -602,6 +602,14 @@ class Array(interfaces.objects.ObjectInterface, collections.abc.Sequence): return 0 raise IndexError(f"Member not present in array template: {child}") + @classmethod + def child_template(cls, template: interfaces.objects.Template, child: str) -> interfaces.objects.Template: + """Returns the template of the child member.""" + if 'subtype' in template.vol and child == 'subtype'@ + return template.vol.subtype + raise IndexError(f"Member not present in array template: {child}") + + @overload def __getitem__(self, i: int) -> interfaces.objects.Template: ... @@ -715,6 +723,15 @@ class AggregateType(interfaces.objects.ObjectInterface): raise IndexError(f"Member not present in template: {child}") return retlist[0] + @classmethod + def child_template(cls, template: interfaces.objects.Template, child: str) -> interfaces.objects.Template: + """Returns the template of a child to its parent.""" + retlist = template.vol.members.get(child, None) + if retlist is None: + raise IndexError(f"Member not present in template: {child}") + return retlist[1] + + @classmethod def has_member(cls, template: interfaces.objects.Template, member_name: str) -> bool: """Returns whether the object would contain a member called diff --git a/volatility3/framework/objects/templates.py b/volatility3/framework/objects/templates.py index 56754d255..e8b523373 100644 --- a/volatility3/framework/objects/templates.py +++ b/volatility3/framework/objects/templates.py @@ -48,6 +48,12 @@ class ObjectTemplate(interfaces.objects.Template): plateProxy`)""" return self.vol.object_class.VolTemplateProxy.relative_child_offset(self, child) + def child_template(self, child: str) -> interfaces.objects.Template: + """Returns the template of a child of the templated object (see + :class:`~volatility3.framework.interfaces.objects.ObjectInterface.VolTem + plateProxy`)""" + return self.vol.object_class.VolTemplateProxy.child_template(self, child) + def replace_child(self, old_child: interfaces.objects.Template, new_child: interfaces.objects.Template) -> None: """Replaces `old_child` for `new_child` in the templated object's child list (see :class:`~volatility3.framework.interfaces.objects.ObjectInterf @@ -99,6 +105,7 @@ class ReferenceTemplate(interfaces.objects.Template): size: ClassVar[Any] = property(_unresolved) replace_child: ClassVar[Any] = _unresolved relative_child_offset: ClassVar[Any] = _unresolved + child_template: ClassVar[Any] = _unresolved has_member: ClassVar[Any] = _unresolved def __call__(self, context: interfaces.context.ContextInterface, object_info: interfaces.objects.ObjectInformation):