Allow unpickling of PrimitiveObjects.

This commit is contained in:
Mike Auty
2018-04-08 22:25:46 +01:00
parent 3f9657a2e1
commit d8f497eb71
2 changed files with 31 additions and 8 deletions
+2 -1
View File
@@ -1,6 +1,5 @@
"""Defines layers for containing data. One layer may combine other layers, map data based on the data itself,
or map a procedure (such as decryption) across another layer of data."""
import collections.abc
import functools
import logging
import math
@@ -9,6 +8,8 @@ import traceback
import typing
from abc import ABCMeta, abstractmethod
import collections.abc
from volatility.framework import constants, exceptions, validity, interfaces
from volatility.framework.interfaces import configuration, context
+29 -7
View File
@@ -48,16 +48,38 @@ class PrimitiveObject(interfaces.objects.ObjectInterface):
type_name: str,
object_info: interfaces.objects.ObjectInformation,
struct_format: str,
new_value = None,
**kwargs) -> typing.Type['PrimitiveObject']:
"""Creates the appropriate class and returns it so that the native type is inherritted
"""Creates the appropriate class and returns it so that the native type is inherited
The only reason the **kwargs is added, is so that the inherriting types can override __init__
without needing to override __new__"""
return cls._struct_type.__new__(cls,
cls._struct_value(context,
struct_format,
object_info.layer_name,
object_info.offset))
without needing to override __new__
We also sneak in new_value, so that we don't have to do expensive (read: impossible) context reads
when unpickling."""
if new_value is None:
value = cls._struct_value(context,
struct_format,
object_info.layer_name,
object_info.offset)
else:
value = new_value
result = super().__new__(cls, value)
# This prevents us having to go read a context layer when recreating after unpickling
result.__new_value = value
return result
def __getnewargs_ex__(self):
"""Make sure that when pickling, all appropiate parameters for new are provided"""
kwargs = {}
for k, v in self._vol.maps[-1].items():
if k not in ["context", "struct_format", "object_info", "type_name"]:
kwargs[k] = v
kwargs['new_value'] = self.__new_value
return (self._context,
self._vol.maps[-2]['type_name'],
self._vol.maps[-3],
self._struct_format), kwargs
@classmethod
def _struct_value(cls,