Layers: Improve non-linear segmented layers

This commit is contained in:
Mike Auty
2021-09-26 01:33:54 +01:00
parent dd35e78dd0
commit ce5bc3ccd8
3 changed files with 10 additions and 7 deletions
+2 -1
View File
@@ -441,7 +441,8 @@ class TranslationLayerInterface(DataLayerInterface, metaclass = ABCMeta):
unprocessed_data = self._context.layers.read(layer, mapped_offset, mapped_length, pad)
processed_data = self._decode_data(unprocessed_data, mapped_offset, layer_offset, sublength)
if len(processed_data) != sublength:
raise ValueError("ProcessedData length does not match expected length of chunk")
raise ValueError(
f"ProcessedData length {len(processed_data)} does not match expected length of chunk {sublength}")
output += processed_data
current_offset += sublength
return output + (b"\x00" * (length - len(output)))
+6 -3
View File
@@ -1,6 +1,7 @@
# This file is Copyright 2020 Volatility Foundation and licensed under the Volatility Software License 1.0
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
#
import bisect
import functools
import json
import math
@@ -211,9 +212,11 @@ class QemuSuspendLayer(segmented.NonLinearlySegmentedLayer):
return index
def _decode_data(self, data: bytes, mapped_offset: int, offset: int, output_length: int) -> bytes:
if mapped_offset in self._compressed:
return (data * 0x1000)[:output_length]
return data
start_offset, _, _, _ = self._segments[bisect.bisect_right(self._segments, (offset, 0xffffffffffffff,)) - 1]
if offset in self._compressed:
data = (data * 0x1000)
result = data[offset - start_offset:output_length + offset - start_offset]
return result
@functools.lru_cache(maxsize = 512)
def read(self, offset: int, length: int, pad: bool = False) -> bytes:
+2 -3
View File
@@ -35,7 +35,7 @@ class NonLinearlySegmentedLayer(interfaces.layers.TranslationLayerInterface, met
def _load_segments(self) -> None:
"""Populates the _segments variable.
Segments must be (address, mapped address, length) and must be
Segments must be (address, mapped address, length, mapped_length) and must be
sorted by address when this method exits
"""
@@ -85,7 +85,6 @@ class NonLinearlySegmentedLayer(interfaces.layers.TranslationLayerInterface, met
if current_offset > logical_offset:
difference = current_offset - logical_offset
logical_offset += difference
mapped_offset += difference
size -= difference
except exceptions.InvalidAddressException:
if not ignore_errors:
@@ -103,7 +102,7 @@ class NonLinearlySegmentedLayer(interfaces.layers.TranslationLayerInterface, met
return
# Crop it to the amount we need left
chunk_size = min(size, length + offset - logical_offset)
yield logical_offset, chunk_size, mapped_offset, chunk_size, self._base_layer
yield logical_offset, chunk_size, mapped_offset, mapped_size, self._base_layer
current_offset += chunk_size
# Terminate if we've gone (or reached) our required limit
if current_offset >= offset + length: