From 640afdda2c149153a66bb7c422f270e6647e14d5 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Thu, 30 Jan 2020 01:07:33 +0000 Subject: [PATCH] Layers: Add in NonLinear Segmented layers --- volatility/framework/layers/crash.py | 2 +- volatility/framework/layers/elf.py | 2 +- volatility/framework/layers/lime.py | 2 +- volatility/framework/layers/segmented.py | 20 ++++++++++++-------- volatility/framework/layers/vmware.py | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/volatility/framework/layers/crash.py b/volatility/framework/layers/crash.py index 76622db84..68abc0937 100644 --- a/volatility/framework/layers/crash.py +++ b/volatility/framework/layers/crash.py @@ -66,7 +66,7 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer): offset = self.headerpages self.header.PhysicalMemoryBlockBuffer.Run.count = self.header.PhysicalMemoryBlockBuffer.NumberOfRuns for x in self.header.PhysicalMemoryBlockBuffer.Run: - segments.append((x.BasePage * 0x1000, offset * 0x1000, x.PageCount * 0x1000)) + segments.append((x.BasePage * 0x1000, offset * 0x1000, x.PageCount * 0x1000, x.PageCount * 0x1000)) # print("Segments {:x} {:x} {:x}".format(x.BasePage * 0x1000, # offset * 0x1000, # x.PageCount * 0x1000)) diff --git a/volatility/framework/layers/elf.py b/volatility/framework/layers/elf.py index ae622536d..022fc4968 100644 --- a/volatility/framework/layers/elf.py +++ b/volatility/framework/layers/elf.py @@ -43,7 +43,7 @@ class Elf64Layer(segmented.SegmentedLayer): # We only want PT_TYPES with valid sizes if phdr.p_type.lookup() == "PT_LOAD" and phdr.p_filesz == phdr.p_memsz and phdr.p_filesz > 0: # Cast these to ints to ensure the offsets don't need reconstructing - segments.append((int(phdr.p_paddr), int(phdr.p_offset), int(phdr.p_memsz))) + segments.append((int(phdr.p_paddr), int(phdr.p_offset), int(phdr.p_memsz), int(phdr.p_memsz))) if len(segments) == 0: raise ElfFormatException(self.name, "No ELF segments defined in {}".format(self._base_layer)) diff --git a/volatility/framework/layers/lime.py b/volatility/framework/layers/lime.py index bebee66df..45e2ac9dc 100644 --- a/volatility/framework/layers/lime.py +++ b/volatility/framework/layers/lime.py @@ -48,7 +48,7 @@ class LimeLayer(segmented.SegmentedLayer): self.name, "Bad start/end 0x{:x}/0x{:x} at file offset 0x{:x}".format(start, end, offset)) segment_length = end - start + 1 - segments.append((start, offset + header_size, segment_length)) + segments.append((start, offset + header_size, segment_length, segment_length)) maxaddr = end offset = offset + header_size + segment_length diff --git a/volatility/framework/layers/segmented.py b/volatility/framework/layers/segmented.py index 7a755320d..01fbc3bc9 100644 --- a/volatility/framework/layers/segmented.py +++ b/volatility/framework/layers/segmented.py @@ -10,7 +10,7 @@ from volatility.framework.configuration import requirements from volatility.framework.layers import linear -class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): +class NonLinearlySegmentedLayer(interfaces.layers.TranslationLayerInterface, metaclass = ABCMeta): """A class to handle a single run-based layer-to-layer mapping. In the documentation "mapped address" or "mapped offset" refers to @@ -25,7 +25,7 @@ class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): super().__init__(context = context, config_path = config_path, name = name, metadata = metadata) self._base_layer = self.config["base_layer"] - self._segments = [] # type: List[Tuple[int, int, int]] + self._segments = [] # type: List[Tuple[int, int, int, int]] self._minaddr = None # type: Optional[int] self._maxaddr = None # type: Optional[int] @@ -49,10 +49,10 @@ class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): except exceptions.InvalidAddressException: return False - def _find_segment(self, offset: int, next: bool = False) -> Tuple[int, int, int]: + def _find_segment(self, offset: int, next: bool = False) -> Tuple[int, int, int, int]: """Finds the segment containing a given offset. - Returns the segment tuple (offset, mapped_offset, length) + Returns the segment tuple (offset, mapped_offset, length, mapped_length) """ if not self._segments: @@ -78,7 +78,7 @@ class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): while not done: try: # Search for the appropriate segment that contains the current_offset - logical_offset, mapped_offset, size = self._find_segment(current_offset) + logical_offset, mapped_offset, size, mapped_size = self._find_segment(current_offset) # If it starts before the current_offset, bring the lower edge up to the right place if current_offset > logical_offset: difference = current_offset - logical_offset @@ -91,7 +91,7 @@ class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): raise try: # Find the next valid segment after our current_offset - logical_offset, mapped_offset, size = self._find_segment(current_offset, next = True) + logical_offset, mapped_offset, size, mapped_size = self._find_segment(current_offset, next = True) # We know that the logical_offset must be greater than current_offset so skip to that value current_offset = logical_offset # If it starts too late then we're done @@ -112,7 +112,7 @@ class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): if not self._segments: raise ValueError("SegmentedLayer must contain some segments") if self._minaddr is None: - mapped, _, _ = self._segments[0] + mapped, _, _, _ = self._segments[0] self._minaddr = mapped return self._minaddr @@ -121,7 +121,7 @@ class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): if not self._segments: raise ValueError("SegmentedLayer must contain some segments") if self._maxaddr is None: - mapped, _, length = self._segments[-1] + mapped, _, length, _ = self._segments[-1] self._maxaddr = mapped + length return self._maxaddr @@ -134,3 +134,7 @@ class SegmentedLayer(linear.LinearlyMappedLayer, metaclass = ABCMeta): @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: return [requirements.TranslationLayerRequirement(name = 'base_layer', optional = False)] + + +class SegmentedLayer(NonLinearlySegmentedLayer, linear.LinearlyMappedLayer, metaclass = ABCMeta): + pass diff --git a/volatility/framework/layers/vmware.py b/volatility/framework/layers/vmware.py index 5c8605fc9..d9b0b4e08 100644 --- a/volatility/framework/layers/vmware.py +++ b/volatility/framework/layers/vmware.py @@ -94,7 +94,7 @@ class VmwareLayer(segmented.SegmentedLayer): offset = tags[("regionPPN", (region, ))][1] * self._page_size mapped_offset = tags[("regionPageNum", (region, ))][1] * self._page_size length = tags[("regionSize", (region, ))][1] * self._page_size - self._segments.append((offset, mapped_offset, length)) + self._segments.append((offset, mapped_offset, length, length)) @property def dependencies(self) -> List[str]: