Allow VolTemplateProxies to include additional useful methods.

This commit is contained in:
Mike Auty
2019-04-17 23:53:36 +01:00
parent e5d6cd3d16
commit 8c76a25b2d
3 changed files with 15 additions and 5 deletions
+8 -3
View File
@@ -19,7 +19,7 @@
#
"""Objects are the core of volatility, and provide pythonic access to interpreted values of data from a layer.
"""
import abc
import collections
import collections.abc
import logging
@@ -166,8 +166,8 @@ class ObjectInterface(metaclass = ABCMeta):
"""Returns whether the object would contain a member called member_name"""
return False
class VolTemplateProxy(object):
"""A container for proxied methods that the ObjectTemplate of this object will call. This primarily to keep
class VolTemplateProxy(metaclass = abc.ABCMeta):
"""A container for proxied methods that the ObjectTemplate of this object will call. This is primarily to keep
methods together for easy organization/management, there is no significant need for it to be a separate class.
The methods of this class *must* be class methods rather than standard methods, to allow for code reuse.
@@ -176,25 +176,30 @@ class ObjectInterface(metaclass = ABCMeta):
new templates for each and every potental object type."""
@classmethod
@abc.abstractmethod
def size(cls, template: 'Template') -> int:
"""Returns the size of the template object"""
@classmethod
@abc.abstractmethod
def children(cls, template: 'Template') -> List['Template']:
"""Returns the children of the template"""
return []
@classmethod
@abc.abstractmethod
def replace_child(cls, template: 'Template', old_child: 'Template', new_child: 'Template') -> None:
"""Substitutes the old_child for the new_child"""
raise KeyError("Template does not contain any children to replace: {}".format(template.vol.type_name))
@classmethod
@abc.abstractmethod
def relative_child_offset(cls, template: 'Template', child: str) -> int:
"""Returns the relative offset from the head of the parent data to the child member"""
raise KeyError("Template does not contain any children: {}".format(template.vol.type_name))
@classmethod
@abc.abstractmethod
def has_member(cls, template: 'Template', member_name: str) -> bool:
"""Returns whether the object would contain a member called member_name"""
return False
-1
View File
@@ -413,7 +413,6 @@ class Enumeration(interfaces.objects.ObjectInterface, int):
self._vol['base_type'] = base_type
@classmethod
@functools.lru_cache(maxsize = 128)
def _generate_inverse_choices(cls, choices: Dict[str, int]) -> Dict[int, str]:
"""Generates the inverse choices for the object"""
inverse_choices = {} # type: Dict[int, str]
+7 -1
View File
@@ -17,7 +17,7 @@
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
# specific language governing rights and limitations under the License.
#
import functools
import logging
from typing import Any, ClassVar, Dict, List, Type
@@ -41,6 +41,12 @@ class ObjectTemplate(interfaces.objects.Template):
super().__init__(type_name = type_name, **arguments)
self._arguments['object_class'] = object_class
proxy_cls = self.vol.object_class.VolTemplateProxy
for method_name in dir(proxy_cls):
if (method_name not in dir(interfaces.objects.ObjectInterface.VolTemplateProxy)
and callable(getattr(proxy_cls, method_name)) and not method_name.startswith('_')):
setattr(self, method_name, functools.partial(getattr(proxy_cls, method_name), self))
@property
def size(self) -> int:
"""Returns the children of the templated object (see :class:`~volatility.framework.interfaces.objects.ObjectInterface.VolTemplateProxy`)"""