mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-21 05:52:22 +02:00
124 lines
6.0 KiB
Python
124 lines
6.0 KiB
Python
import datetime
|
|
import logging
|
|
import typing
|
|
|
|
import volatility.framework.interfaces.plugins as plugins
|
|
from volatility.framework import objects, renderers
|
|
from volatility.framework.configuration import requirements
|
|
from volatility.framework.layers.registry import RegistryHive
|
|
from volatility.framework.renderers import TreeGrid
|
|
from volatility.framework.symbols.windows.extensions.registry import RegValueTypes
|
|
|
|
vollog = logging.getLogger(__name__)
|
|
|
|
|
|
class PrintKey(plugins.PluginInterface):
|
|
"""Lists the registry keys under a hive or specific key value"""
|
|
|
|
@classmethod
|
|
def get_requirements(cls):
|
|
return [requirements.TranslationLayerRequirement(name = 'primary',
|
|
description = 'Kernel Address Space',
|
|
architectures = ["Intel32", "Intel64"]),
|
|
requirements.SymbolRequirement(name = "nt_symbols",
|
|
description = "Windows OS"),
|
|
requirements.IntRequirement(name = 'offset',
|
|
description = "Hive Offset",
|
|
default = None,
|
|
optional = True),
|
|
requirements.StringRequirement(name = 'key',
|
|
description = "Key to start from",
|
|
default = None,
|
|
optional = True),
|
|
requirements.BooleanRequirement(name = 'recurse',
|
|
description = 'Recurses through keys',
|
|
default = False,
|
|
optional = True)]
|
|
|
|
def update_configuration(self):
|
|
"""No operation since all values provided by config/requirements initially"""
|
|
|
|
def hive_walker(self, hive: RegistryHive, node_path: typing.Sequence[objects.Struct] = None, key_path: str = None) \
|
|
-> typing.Generator:
|
|
"""Walks through a set of nodes from a given node (last one in node_path).
|
|
Avoids loops by not traversing into nodes already present in the node_path
|
|
"""
|
|
if not node_path:
|
|
node_path = [hive.get_node(hive.root_cell_offset)]
|
|
if not isinstance(node_path, list) or len(node_path) < 1:
|
|
vollog.warning("Hive walker was not passed a valid node_path (or None)")
|
|
raise StopIteration
|
|
node = node_path[-1]
|
|
if key_path is None:
|
|
key_path = node.get_key_path()
|
|
unix_time = node.LastWriteTime.QuadPart // 10000000
|
|
unix_time = unix_time - 11644473600
|
|
|
|
for key_node in node.get_subkeys():
|
|
result = (key_path.count("\\"),
|
|
(str(datetime.datetime.utcfromtimestamp(unix_time)),
|
|
renderers.format_hints.Hex(hive.hive_offset),
|
|
"Key",
|
|
key_path,
|
|
key_node.get_name(),
|
|
"",
|
|
key_node.get_volatile()))
|
|
yield result
|
|
|
|
for value_node in node.get_values():
|
|
result = (key_path.count("\\"),
|
|
(str(datetime.datetime.utcfromtimestamp(unix_time)),
|
|
renderers.format_hints.Hex(hive.hive_offset),
|
|
RegValueTypes(value_node.Type).name,
|
|
key_path,
|
|
value_node.get_name(),
|
|
str(value_node.decode_data()),
|
|
node.get_volatile()))
|
|
yield result
|
|
|
|
if self.config['recurse']:
|
|
for sub_node in node.get_subkeys():
|
|
if sub_node.vol.offset not in [x.vol.offset for x in node_path]:
|
|
yield from self.hive_walker(hive, node_path + [sub_node], key_path + "\\" + sub_node.get_name())
|
|
|
|
def registry_walker(self):
|
|
"""Walks through a registry, hive by hive"""
|
|
if self.config.get('offset', None) is None:
|
|
try:
|
|
import volatility.plugins.windows.hivelist as hivelist
|
|
plugin_config_path = self.make_subconfig(primary = self.config['primary'],
|
|
nt_symbols = self.config['nt_symbols'])
|
|
plugin = hivelist.HiveList(self.context, plugin_config_path)
|
|
hive_offsets = [hive.vol.offset for hive in plugin.list_hives()]
|
|
except:
|
|
vollog.warning("Unable to import windows.hivelist plugin, please provide a hive offset")
|
|
raise ValueError("Unable to import windows.hivelist plugin, please provide a hive offset")
|
|
else:
|
|
hive_offsets = [self.config['offset']]
|
|
|
|
for hive_offset in hive_offsets:
|
|
# Construct the hive
|
|
reg_config_path = self.make_subconfig(hive_offset = hive_offset,
|
|
base_layer = self.config['primary'],
|
|
nt_symbols = self.config['nt_symbols'])
|
|
hive = RegistryHive(self.context, reg_config_path, name = 'hive' + hex(hive_offset), os = 'Windows')
|
|
self.context.memory.add_layer(hive)
|
|
|
|
# Walk it
|
|
if 'key' in self.config:
|
|
node_path = hive.get_key(self.config['key'], return_list = True)
|
|
else:
|
|
node_path = [hive.get_node(hive.root_cell_offset)]
|
|
yield from self.hive_walker(hive, node_path)
|
|
|
|
def run(self):
|
|
|
|
return TreeGrid(columns = [('Last Write Time', str),
|
|
('Hive Offset', renderers.format_hints.Hex),
|
|
('Type', str),
|
|
('Key', str),
|
|
('Name', str),
|
|
('Data', str),
|
|
('Volatile', bool)],
|
|
generator = self.registry_walker())
|