From 1e175b5d3bf25dbc674bc2bda800c82b737cca70 Mon Sep 17 00:00:00 2001 From: David McDonald Date: Thu, 20 Mar 2025 15:11:37 -0500 Subject: [PATCH] Objects: rework new `get_raw_value()` method Per code review recommendations, splits the `_unmarshall` classmethod into two components, one of which retrieves the raw value, and the other that returns the masked pointer. The `get_raw_value` method now calls the `_get_raw_value` classmethod using its instance information. --- volatility3/framework/objects/__init__.py | 35 ++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/volatility3/framework/objects/__init__.py b/volatility3/framework/objects/__init__.py index 9dd30db63..b863e103b 100644 --- a/volatility3/framework/objects/__init__.py +++ b/volatility3/framework/objects/__init__.py @@ -402,26 +402,35 @@ class Pointer(Integer): pointer should be recast. The "pointer" must always live within the space (even if the data provided is invalid). """ + mask = context.layers[object_info.native_layer_name].address_mask + new = ( + cls._get_raw_value( + context, data_format, object_info.layer_name, object_info.offset + ) + & mask + ) + return new + + @classmethod + def _get_raw_value( + cls, + context: interfaces.context.ContextInterface, + data_format: DataFormatInfo, + layer_name: str, + offset: int, + ) -> int: length, endian, signed = data_format if signed: raise ValueError("Pointers cannot have signed values") - mask = context.layers[object_info.native_layer_name].address_mask - data = context.layers.read(object_info.layer_name, object_info.offset, length) + data = context.layers.read(layer_name, offset, length) value = int.from_bytes(data, byteorder=endian, signed=signed) - return value & mask + return value def get_raw_value(self) -> int: - formats = { - 4: "I", - 8: "Q", - } - length = self.vol.data_format.length - endian = self.vol.data_format.byteorder - raw_data = self._context.layers[self.vol.layer_name].read( - self.vol.offset, length + raw = self._get_raw_value( + self._context, self.vol.data_format, self.vol.layer_name, self.vol.offset ) - struct_format = ("<" if endian == "little" else ">") + formats[length] - return struct.unpack(struct_format, raw_data)[0] + return raw def dereference( self, layer_name: Optional[str] = None