Source code for volatility3.plugins.windows.deskscan

# This file is Copyright 2025 Volatility Foundation and licensed under the Volatility Software License 1.0
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
#
import logging
from typing import List, Iterable, Tuple

from volatility3.framework import interfaces
from volatility3.framework.configuration import requirements
from volatility3.framework.renderers import format_hints
from volatility3.plugins.windows import desktops, windowstations

vollog = logging.getLogger(__name__)


[docs] class DeskScan(desktops.Desktops): """Scans for the Desktop instances of each Window Station""" _required_framework_version = (2, 0, 0) _version = (1, 0, 0) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.implementation = self.scan_desktops
[docs] @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: # Since we're calling the plugin, make sure we have the plugin's requirements return [ requirements.ModuleRequirement( name="kernel", description="Windows kernel", architectures=["Intel32", "Intel64"], ), requirements.VersionRequirement( name="desktops", component=desktops.Desktops, version=(1, 0, 0) ), requirements.VersionRequirement( name="windowstations", component=windowstations.WindowStations, version=(1, 0, 0), ), ]
[docs] @classmethod def scan_desktops( cls, context: interfaces.context.ContextInterface, config_path: str, kernel_module_name: str, ) -> Iterable[Tuple[int, str, int, str, str, int]]: """ Yields the information about each desktop and desktop thread needed for analysis The tuple yielded includes the: Virtual address of the desktop The window station name The session id Desktop name Process name Process ID (PID) """ kernel = context.modules[kernel_module_name] for desktop in windowstations.WindowStations.scan_gui_object( context, config_path, kernel_module_name, b"Desk", "tagDESKTOP" ): desktop_name = desktop.get_name(kernel.symbol_table_name) if not desktop_name: continue winsta = desktop.get_window_station() if not winsta: continue winsta_name, session_id = winsta.get_info(kernel.symbol_table_name) if not winsta_name or session_id is None: continue for _thread, process_name, process_pid in desktop.get_threads(): yield ( format_hints.Hex(desktop.vol.offset), winsta_name, session_id, desktop_name, process_name, process_pid, )