Merge pull request #549 from volatilityfoundation/feature/intel-coalesce-by-default

Layers: Coalesce intel mapping responses
This commit is contained in:
ikelos
2021-08-25 16:46:43 +01:00
committed by GitHub
2 changed files with 34 additions and 32 deletions
+33 -2
View File
@@ -193,6 +193,38 @@ class Intel(linear.LinearlyMappedLayer):
"""Returns a sorted iterable of (offset, sublength, mapped_offset, mapped_length, layer)
mappings.
This allows translation layers to provide maps of contiguous
regions in one layer
"""
stashed_offset = stashed_mapped_offset = stashed_size = stashed_mapped_size = stashed_map_layer = None
for offset, size, mapped_offset, mapped_size, map_layer in self._mapping(offset, length, ignore_errors):
if stashed_offset is None or (stashed_offset + stashed_size != offset) or (
stashed_mapped_offset + stashed_mapped_size != mapped_offset) or (stashed_map_layer != map_layer):
# The block isn't contiguous
if stashed_offset is not None:
yield stashed_offset, stashed_size, stashed_mapped_offset, stashed_mapped_size, stashed_map_layer
# Update all the stashed values after output
stashed_offset = offset
stashed_mapped_offset = mapped_offset
stashed_size = size
stashed_mapped_size = mapped_size
stashed_map_layer = map_layer
else:
# Part of an existing block
stashed_size += size
stashed_mapped_size += mapped_size
# Yield whatever's left
if (stashed_offset is not None and stashed_mapped_offset is not None and stashed_size is not None
and stashed_mapped_size is not None and stashed_map_layer is not None):
yield stashed_offset, stashed_size, stashed_mapped_offset, stashed_mapped_size, stashed_map_layer
def _mapping(self,
offset: int,
length: int,
ignore_errors: bool = False) -> Iterable[Tuple[int, int, int, int, str]]:
"""Returns a sorted iterable of (offset, sublength, mapped_offset, mapped_length, layer)
mappings.
This allows translation layers to provide maps of contiguous
regions in one layer
"""
@@ -328,12 +360,11 @@ class WindowsIntelPAE(WindowsMixin, IntelPAE):
class WindowsIntel32e(WindowsMixin, Intel32e):
# TODO: Fix appropriately in a future release.
# Currently just a temprorary workaround to deal with custom bit flag
# in the PFN field for pages in transition state.
# See https://github.com/volatilityfoundation/volatility3/pull/475
_maxphyaddr = 45
def _translate(self, offset: int) -> Tuple[int, int, str]:
return self._translate_swap(self, offset, self._bits_per_register // 2)
@@ -25,8 +25,6 @@ class Memmap(interfaces.plugins.PluginInterface):
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.BooleanRequirement(name = 'coalesce', description = 'Clump output where possible',
default = False, optional = True),
requirements.IntRequirement(name = 'pid',
description = "Process ID to include (all other processes are excluded)",
optional = True),
@@ -36,29 +34,6 @@ class Memmap(interfaces.plugins.PluginInterface):
optional = True)
]
@classmethod
def coalesce(cls, mapping_generator):
stashed_offset = stashed_mapped_offset = stashed_size = stashed_mapped_size = stashed_mapped_layer = None
for offset, size, mapped_offset, mapped_size, map_layer in mapping_generator:
if stashed_offset is None or (stashed_offset + stashed_size != offset) or (
stashed_mapped_offset + stashed_mapped_size != mapped_offset) or (stashed_map_layer != map_layer):
# The block isn't contiguous
if stashed_offset is not None:
yield stashed_offset, stashed_size, stashed_mapped_offset, stashed_mapped_size, stashed_map_layer
# Update all the stashed values after output
stashed_offset = offset
stashed_mapped_offset = mapped_offset
stashed_size = size
stashed_mapped_size = mapped_size
stashed_map_layer = map_layer
else:
# Part of an existing block
stashed_size += size
stashed_mapped_size += mapped_size
# Yield whatever's left
if stashed_offset is not None:
yield stashed_offset, stashed_size, stashed_mapped_offset, stashed_mapped_size, stashed_map_layer
def _generator(self, procs):
for proc in procs:
pid = "Unknown"
@@ -72,10 +47,6 @@ class Memmap(interfaces.plugins.PluginInterface):
excp.layer_name))
continue
if self.config['coalesce']:
coalesce = self.coalesce
else:
coalesce = lambda x: x
if self.config['dump']:
file_handle = self.open(f"pid.{pid}.dmp")
else:
@@ -83,7 +54,7 @@ class Memmap(interfaces.plugins.PluginInterface):
file_handle = contextlib.ExitStack()
with file_handle as file_data:
file_offset = 0
for mapval in coalesce(proc_layer.mapping(0x0, proc_layer.maximum_address, ignore_errors = True)):
for mapval in proc_layer.mapping(0x0, proc_layer.maximum_address, ignore_errors = True):
offset, size, mapped_offset, mapped_size, maplayer = mapval
file_output = "Disabled"