Windows: Add coalesce support to memmap

This commit is contained in:
Mike Auty
2021-08-05 17:28:36 +01:00
parent 1611a72eb9
commit 8745931dea
@@ -27,6 +27,8 @@ class Memmap(interfaces.plugins.PluginInterface):
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "nt_symbols", description = "Windows kernel symbols"),
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,6 +38,29 @@ 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"
@@ -49,6 +74,10 @@ 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:
@@ -56,11 +85,10 @@ class Memmap(interfaces.plugins.PluginInterface):
file_handle = contextlib.ExitStack()
with file_handle as file_data:
file_offset = 0
for mapval in proc_layer.mapping(0x0, proc_layer.maximum_address, ignore_errors = True):
for mapval in coalesce(proc_layer.mapping(0x0, proc_layer.maximum_address, ignore_errors = True)):
offset, size, mapped_offset, mapped_size, maplayer = mapval
file_output = "Disabled"
file_offset += size
if self.config['dump']:
try:
data = proc_layer.read(offset, size, pad = True)
@@ -71,15 +99,19 @@ class Memmap(interfaces.plugins.PluginInterface):
vollog.debug("Unable to write {}'s address {} to {}".format(
proc_layer_name, offset, file_handle.preferred_filename))
yield (0, (format_hints.Hex(offset), format_hints.Hex(mapped_offset), format_hints.Hex(mapped_size),
yield (0, (format_hints.Hex(offset), format_hints.Hex(mapped_offset),
format_hints.Hex(mapped_size),
format_hints.Hex(file_offset), file_output))
file_offset += mapped_size
offset += mapped_size
def run(self):
filter_func = pslist.PsList.create_pid_filter([self.config.get('pid', None)])
return renderers.TreeGrid([("Virtual", format_hints.Hex), ("Physical", format_hints.Hex),
("Size", format_hints.Hex), ("Offset in File", format_hints.Hex), ("File output", str)],
("Size", format_hints.Hex), ("Offset in File", format_hints.Hex),
("File output", str)],
self._generator(
pslist.PsList.list_processes(context = self.context,
layer_name = self.config['primary'],