mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-09 19:27:39 +02:00
Plugins: Make layerwiter more configurable
This adds support for dumping multiple layers at once, listing available layers and selects the highest non-mapped layer. Mapping is specified in the metadata and currently is only applied to intel layers.
This commit is contained in:
@@ -28,6 +28,7 @@ class Intel(linear.LinearlyMappedLayer):
|
||||
_maxvirtaddr = _maxphyaddr
|
||||
_structure = [('page directory', 10, False), ('page table', 10, True)]
|
||||
_direct_metadata = collections.ChainMap({'architecture': 'Intel32'},
|
||||
{'mapped': True},
|
||||
interfaces.layers.TranslationLayerInterface._direct_metadata)
|
||||
|
||||
def __init__(self,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import List, Optional, Type
|
||||
|
||||
from volatility.framework import renderers, interfaces, constants, exceptions
|
||||
@@ -16,7 +15,6 @@ vollog = logging.getLogger(__name__)
|
||||
class LayerWriter(plugins.PluginInterface):
|
||||
"""Runs the automagics and writes out the primary layer produced by the stacker."""
|
||||
|
||||
default_output_name = "output.raw"
|
||||
default_block_size = 0x500000
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
@@ -28,14 +26,19 @@ class LayerWriter(plugins.PluginInterface):
|
||||
requirements.TranslationLayerRequirement(name = 'primary',
|
||||
description = 'Memory layer for the kernel',
|
||||
architectures = ["Intel32", "Intel64"]),
|
||||
requirements.StringRequirement(name = 'output',
|
||||
description = 'Filename to output the chosen layer',
|
||||
optional = True,
|
||||
default = cls.default_output_name),
|
||||
requirements.IntRequirement(name = 'block_size',
|
||||
description = "Size of blocks to copy over",
|
||||
default = cls.default_block_size,
|
||||
optional = True)
|
||||
optional = True),
|
||||
requirements.BooleanRequirement(name = 'list',
|
||||
description = 'List available layers',
|
||||
default = False,
|
||||
optional = True),
|
||||
requirements.ListRequirement(name = 'layers',
|
||||
element_type = str,
|
||||
description = 'Names of layer to write',
|
||||
default = None,
|
||||
optional = True)
|
||||
]
|
||||
|
||||
@classmethod
|
||||
@@ -75,24 +78,44 @@ class LayerWriter(plugins.PluginInterface):
|
||||
return file_handle
|
||||
|
||||
def _generator(self):
|
||||
if self.config['primary'] not in self.context.layers:
|
||||
yield 0, ('Layer Name does not exist',)
|
||||
elif os.path.exists(self.config.get('output', self.default_output_name)):
|
||||
yield 0, ('Refusing to overwrite existing output file',)
|
||||
if self.config['list']:
|
||||
for name in self.context.layers:
|
||||
yield 0, (name,)
|
||||
else:
|
||||
output_name = self.config.get('output', self.default_output_name)
|
||||
try:
|
||||
file_handle = self.write_layer(self.context,
|
||||
self.config['primary'],
|
||||
output_name,
|
||||
self.open,
|
||||
self.config.get('block_size', self.default_block_size),
|
||||
progress_callback = self._progress_callback)
|
||||
file_handle.close()
|
||||
except IOError as excp:
|
||||
yield 0, ('Layer cannot be written to {}: {}'.format(self.config['output_name'], excp),)
|
||||
import pdb
|
||||
pdb.set_trace()
|
||||
# Choose the most recently added layer that isn't virtual
|
||||
if self.config['layers'] is None:
|
||||
self.config['layers'] = []
|
||||
for name in self.context.layers:
|
||||
if not self.context.layers[name].metadata.get('mapped', False):
|
||||
self.config['layers'] = [name]
|
||||
|
||||
yield 0, ('Layer has been written to {}'.format(output_name),)
|
||||
for name in self.config['layers']:
|
||||
# Check the layer exists and validate the output file
|
||||
if name not in self.context.layers:
|
||||
yield 0, ('Layer Name {} does not exist'.format(name),)
|
||||
else:
|
||||
output_name = self.config.get('output', ".".join([name, "raw"]))
|
||||
try:
|
||||
file_handle = self.write_layer(self.context,
|
||||
name,
|
||||
output_name,
|
||||
self.open,
|
||||
self.config.get('block_size', self.default_block_size),
|
||||
progress_callback = self._progress_callback)
|
||||
file_handle.close()
|
||||
except IOError as excp:
|
||||
yield 0, ('Layer cannot be written to {}: {}'.format(self.config['output_name'], excp),)
|
||||
|
||||
yield 0, ('Layer has been written to {}'.format(output_name),)
|
||||
|
||||
def _generate_layers(self):
|
||||
"""List layer names from this run"""
|
||||
for name in self.context.layers:
|
||||
yield (0, (name,))
|
||||
|
||||
def run(self):
|
||||
if self.config['list']:
|
||||
return renderers.TreeGrid([("Layer name", str)], self._generate_layers())
|
||||
return renderers.TreeGrid([("Status", str)], self._generator())
|
||||
|
||||
Reference in New Issue
Block a user