From dbc837474c9c1d6096abd7cd27496677f0a36e7b Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Thu, 1 Aug 2024 14:23:22 -0500 Subject: [PATCH 01/17] #816 - initial support for Windows Windows Server 2022 (10.0.20348) --- .../framework/plugins/windows/consoles.py | 786 ++++++++++++++++++ .../consoles-win10-20348-2461-x64.json | 595 +++++++++++++ .../consoles/consoles-win10-20348-x64.json | 595 +++++++++++++ .../symbols/windows/extensions/consoles.py | 303 +++++++ 4 files changed, 2279 insertions(+) create mode 100644 volatility3/framework/plugins/windows/consoles.py create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json create mode 100644 volatility3/framework/symbols/windows/extensions/consoles.py diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py new file mode 100644 index 000000000..f6bbb3ae7 --- /dev/null +++ b/volatility3/framework/plugins/windows/consoles.py @@ -0,0 +1,786 @@ +# This file is Copyright 2024 Volatility Foundation and licensed under the Volatility Software License 1.0 +# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 +# + +# This module attempts to locate windows console histories. + +import logging +import os +import struct +from typing import Tuple, Generator, Set, Dict, Any, Type + +from volatility3.framework import interfaces, symbols, exceptions +from volatility3.framework import renderers +from volatility3.framework.configuration import requirements +from volatility3.framework.layers import scanners +from volatility3.framework.objects import utility +from volatility3.framework.renderers import format_hints +from volatility3.framework.symbols import intermed +from volatility3.framework.symbols.windows import pdbutil, versions +from volatility3.framework.symbols.windows.extensions import pe, consoles +from volatility3.plugins.windows import pslist, vadinfo, info, verinfo +from volatility3.plugins.windows.registry import hivelist + + +try: + import capstone + + has_capstone = True +except ImportError: + has_capstone = False + +vollog = logging.getLogger(__name__) + + +class Consoles(interfaces.plugins.PluginInterface): + """Looks for Windows console buffers""" + + _required_framework_version = (2, 4, 0) + + @classmethod + def get_requirements(cls): + # 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="pslist", component=pslist.PsList, version=(2, 0, 0) + ), + requirements.VersionRequirement( + name="pdbutil", component=pdbutil.PDBUtility, version=(1, 0, 0) + ), + requirements.PluginRequirement( + name="hivelist", plugin=hivelist.HiveList, version=(1, 0, 0) + ), + requirements.BooleanRequirement( + name="no_registry", + description="Don't search the registry for possible values of CommandHistorySize and HistoryBufferMax", + optional=True, + default=False, + ), + requirements.ListRequirement( + name="max_history", + element_type=int, + description="CommandHistorySize values to search for.", + optional=True, + default=[50], + ), + requirements.ListRequirement( + name="max_buffers", + element_type=int, + description="HistoryBufferMax values to search for.", + optional=True, + default=[4], + ), + ] + + @classmethod + def find_conhost_proc( + cls, proc_list: Generator[interfaces.objects.ObjectInterface, None, None] + ) -> Tuple[interfaces.context.ContextInterface, str]: + """ + Walks the process list and returns the conhost instances. + + Args: + proc_list: The process list generator + + Return: + The process object and layer name for conhost + """ + + for proc in proc_list: + try: + proc_id = proc.UniqueProcessId + proc_layer_name = proc.add_process_layer() + + yield proc, proc_layer_name + + except exceptions.InvalidAddressException as excp: + vollog.debug( + "Process {}: invalid address {} in layer {}".format( + proc_id, excp.invalid_address, excp.layer_name + ) + ) + + @classmethod + def find_conhostexe( + cls, conhost_proc: interfaces.context.ContextInterface + ) -> Tuple[int, int]: + """ + Finds the base address of conhost.exe + + Args: + conhost_proc: the process object for conhost.exe + + Returns: + A tuple of: + conhostexe_base: the base address of conhost.exe + conhostexe_size: the size of the VAD for conhost.exe + """ + for vad in conhost_proc.get_vad_root().traverse(): + filename = vad.get_file_name() + + if isinstance(filename, str) and filename.lower().endswith("conhost.exe"): + base = vad.get_start() + return base, vad.get_size() + + return None, None + + @classmethod + def determine_conhost_version( + cls, + context: interfaces.context.ContextInterface, + layer_name: str, + nt_symbol_table: str, + ) -> Tuple[str, Type]: + """Tries to determine which symbol filename to use for the image's console information. This is similar to the + netstat plugin. + + Args: + context: The context to retrieve required elements (layers, symbol tables) from + layer_name: The name of the layer on which to operate + nt_symbol_table: The name of the table containing the kernel symbols + + Returns: + The filename of the symbol table to use and the associated class types. + """ + + is_64bit = symbols.symbol_table_is_64bit(context, nt_symbol_table) + + is_18363_or_later = versions.is_win10_18363_or_later( + context=context, symbol_table=nt_symbol_table + ) + + if is_64bit: + arch = "x64" + else: + arch = "x86" + + vers = info.Info.get_version_structure(context, layer_name, nt_symbol_table) + + kuser = info.Info.get_kuser_structure(context, layer_name, nt_symbol_table) + + try: + vers_minor_version = int(vers.MinorVersion) + nt_major_version = int(kuser.NtMajorVersion) + nt_minor_version = int(kuser.NtMinorVersion) + except ValueError: + # vers struct exists, but is not an int anymore? + raise NotImplementedError( + "Kernel Debug Structure version format not supported!" + ) + except: + # unsure what to raise here. Also, it might be useful to add some kind of fallback, + # either to a user-provided version or to another method to determine tcpip.sys's version + raise exceptions.VolatilityException( + "Kernel Debug Structure missing VERSION/KUSER structure, unable to determine Windows version!" + ) + + vollog.debug( + "Determined OS Version: {}.{} {}.{}".format( + kuser.NtMajorVersion, + kuser.NtMinorVersion, + vers.MajorVersion, + vers.MinorVersion, + ) + ) + + if nt_major_version == 10 and arch == "x64": + # win10 x64 has an additional class type we have to include. + class_types = consoles.win10_x64_class_types + else: + # default to general class types + class_types = consoles.class_types + + # these versions are listed explicitly because symbol files differ based on + # version *and* architecture. this is currently the clearest way to show + # the differences, even if it introduces a fair bit of redundancy. + # furthermore, it is easy to append new versions. + if arch == "x86": + version_dict = {} + else: + version_dict = { + (10, 0, 20348, 1): "consoles-win10-20348-x64", + (10, 0, 20348, 1970): "consoles-win10-20348-1970-x64", + (10, 0, 20348, 2461): "consoles-win10-20348-2461-x64", + (10, 0, 20348, 2520): "consoles-win10-20348-2461-x64", + } + + # we do not need to check for conhost's specific FileVersion in every case + conhost_mod_version = 0 # keep it 0 as a default + + # special use cases + + # Win10_18363 is not recognized by windows.info as 18363 + # because all kernel file headers and debug structures report 18363 as + # "10.0.18362.1198" with the last part being incremented. However, we can use + # os_distinguisher to differentiate between 18362 and 18363 + if vers_minor_version == 18362 and is_18363_or_later: + vollog.debug( + "Detected 18363 data structures: working with 18363 symbol table." + ) + vers_minor_version = 18363 + + # we need to define additional version numbers (which are then found via conhost.exe's FileVersion header) in case there is + # ambiguity _within_ an OS version. If such a version number (last number of the tuple) is defined for the current OS + # we need to inspect conhost.exe's headers to see if we can grab the precise version + if [ + (a, b, c, d) + for a, b, c, d in version_dict + if (a, b, c) == (nt_major_version, nt_minor_version, vers_minor_version) + and d != 0 + ]: + vollog.debug( + "Requiring further version inspection due to OS version by checking conhost.exe's FileVersion header" + ) + # the following is IntelLayer specific and might need to be adapted to other architectures. + physical_layer_name = context.layers[layer_name].config.get( + "memory_layer", None + ) + if physical_layer_name: + ver = verinfo.VerInfo.find_version_info( + context, physical_layer_name, "CONHOST.EXE" + ) + + if ver: + conhost_mod_version = ver[3] + vollog.debug( + "Determined conhost.exe's FileVersion: {}".format( + conhost_mod_version + ) + ) + else: + vollog.debug("Could not determine conhost.exe's FileVersion.") + else: + vollog.debug( + "Unable to retrieve physical memory layer, skipping FileVersion check." + ) + + # when determining the symbol file we have to consider the following cases: + # the determined version's symbol file is found by intermed.create -> proceed + # the determined version's symbol file is not found by intermed -> intermed will throw an exc and abort + # the determined version has no mapped symbol file -> if win10 use latest, otherwise throw exc + # windows version cannot be determined -> throw exc + + filename = version_dict.get( + ( + nt_major_version, + nt_minor_version, + vers_minor_version, + conhost_mod_version, + ) + ) + + if not filename: + # no match on filename means that we possibly have a version newer than those listed here. + # try to grab the latest supported version of the current image NT version. If that symbol + # version does not work, support has to be added manually. + current_versions = [ + (nt_maj, nt_min, vers_min, tcpip_ver) + for nt_maj, nt_min, vers_min, tcpip_ver in version_dict + if nt_maj == nt_major_version + and nt_min == nt_minor_version + and tcpip_ver <= conhost_mod_version + ] + current_versions.sort() + + if current_versions: + latest_version = current_versions[-1] + + filename = version_dict.get(latest_version) + + vollog.debug( + f"Unable to find exact matching symbol file, going with latest: {filename}" + ) + + else: + raise NotImplementedError( + "This version of Windows is not supported: {}.{} {}.{}!".format( + nt_major_version, + nt_minor_version, + vers.MajorVersion, + vers_minor_version, + ) + ) + + vollog.debug(f"Determined symbol filename: {filename}") + + return filename, class_types + + @classmethod + def create_conhost_symbol_table( + cls, + context: interfaces.context.ContextInterface, + layer_name: str, + nt_symbol_table: str, + config_path: str, + ) -> str: + """Creates a symbol table for TCP Listeners and TCP/UDP Endpoints. + + Args: + context: The context to retrieve required elements (layers, symbol tables) from + layer_name: The name of the layer on which to operate + nt_symbol_table: The name of the table containing the kernel symbols + config_path: The config path where to find symbol files + + Returns: + The name of the constructed symbol table + """ + table_mapping = {"nt_symbols": nt_symbol_table} + + symbol_filename, class_types = cls.determine_conhost_version( + context, + layer_name, + nt_symbol_table, + ) + + vollog.debug(f"Using symbol file '{symbol_filename}' and types {class_types}") + + return intermed.IntermediateSymbolTable.create( + context, + config_path, + os.path.join("windows", "consoles"), + symbol_filename, + class_types=class_types, + table_mapping=table_mapping, + ) + + @classmethod + def get_console_info( + cls, + context: interfaces.context.ContextInterface, + kernel_layer_name: str, + kernel_table_name: str, + config_path: str, + procs: Generator[interfaces.objects.ObjectInterface, None, None], + max_history: Set[int], + max_buffers: Set[int], + ) -> Tuple[ + interfaces.context.ContextInterface, + interfaces.context.ContextInterface, + Dict[str, Any], + ]: + """Extracts the cmdline from PEB + + Args: + context: The context to retrieve required elements (layers, symbol tables) from + kernel_layer_name: The name of the layer on which to operate + kernel_table_name: The name of the table containing the kernel symbols + config_path: The config path where to find symbol files + procs: list of process objects + max_history: an initial set of CommandHistorySize values + max_buffers: an initial list of HistoryBufferMax values + + Returns: + The conhost process object, the console information structure, a dictionary of properties for + that console information structure. + """ + + conhost_symbol_table = cls.create_conhost_symbol_table( + context, kernel_layer_name, kernel_table_name, config_path + ) + + for conhost_proc, proc_layer_name in cls.find_conhost_proc(procs): + if not conhost_proc: + vollog.info( + "Unable to find a valid conhost.exe process in the process list. Analysis cannot proceed." + ) + continue + vollog.debug( + f"Found conhost process {conhost_proc} with pid {conhost_proc.UniqueProcessId}" + ) + + conhostexe_base, conhostexe_size = cls.find_conhostexe(conhost_proc) + if not conhostexe_base: + vollog.info( + "Unable to find the location of conhost.exe. Analysis cannot proceed." + ) + continue + vollog.debug(f"Found conhost.exe base at {conhostexe_base:#x}") + + proc_layer = context.layers[proc_layer_name] + + conhost_module = context.module( + conhost_symbol_table, proc_layer_name, offset=conhostexe_base + ) + + # scan for potential _CONSOLE_INFORMATION structures by using the CommandHistorySize + for max_history_value in max_history: + max_history_bytes = struct.pack("H", max_history_value) + vollog.debug( + f"Scanning for CommandHistorySize value: {max_history_bytes}" + ) + for address in proc_layer.scan( + context, + scanners.BytesScanner(max_history_bytes), + sections=[(conhostexe_base, conhostexe_size)], + ): + + console_properties = [] + + try: + console_info = conhost_module.object( + "_CONSOLE_INFORMATION", + offset=address + - conhost_module.get_type( + "_CONSOLE_INFORMATION" + ).relative_child_offset("CommandHistorySize"), + absolute=True, + ) + + if not any( + [ + console_info.is_valid(max_buffer) + for max_buffer in max_buffers + ] + ): + continue + + vollog.debug( + f"Getting Console Information properties for {console_info}" + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.ScreenX", + "address": console_info.ScreenX.vol.offset, + "data": console_info.ScreenX, + } + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.ScreenY", + "address": console_info.ScreenY.vol.offset, + "data": console_info.ScreenY, + } + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.CommandHistorySize", + "address": console_info.CommandHistorySize.vol.offset, + "data": console_info.CommandHistorySize, + } + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.HistoryBufferCount", + "address": console_info.HistoryBufferCount.vol.offset, + "data": console_info.HistoryBufferCount, + } + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.HistoryBufferMax", + "address": console_info.HistoryBufferMax.vol.offset, + "data": console_info.HistoryBufferMax, + } + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.Title", + "address": console_info.Title.vol.offset, + "data": console_info.get_title(), + } + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.OriginalTitle", + "address": console_info.OriginalTitle.vol.offset, + "data": console_info.get_original_title(), + } + ) + + vollog.debug( + f"Getting ConsoleProcessList entries for {console_info.ConsoleProcessList}" + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.ProcessCount", + "address": console_info.ProcessCount.vol.offset, + "data": console_info.ProcessCount, + } + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.ConsoleProcessList", + "address": console_info.ConsoleProcessList.vol.offset, + "data": "", + } + ) + for index, attached_proc in enumerate( + console_info.get_processes() + ): + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.ConsoleProcessList.ConsoleProcess_{index}", + "address": attached_proc.ConsoleProcess.dereference().vol.offset, + "data": "", + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.ConsoleProcessList.ConsoleProcess_{index}_ProcessId", + "address": attached_proc.ConsoleProcess.ProcessId.vol.offset, + "data": attached_proc.ConsoleProcess.ProcessId, + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.ConsoleProcessList.ConsoleProcess_{index}_ProcessHandle", + "address": attached_proc.ConsoleProcess.ProcessHandle.vol.offset, + "data": hex( + attached_proc.ConsoleProcess.ProcessHandle + ), + } + ) + + vollog.debug( + f"Getting HistoryList entries for {console_info.HistoryList}" + ) + console_properties.append( + { + "name": "_CONSOLE_INFORMATION.HistoryList", + "address": console_info.HistoryList.vol.offset, + "data": "", + } + ) + for index, command_history in enumerate( + console_info.get_histories() + ): + try: + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}", + "address": command_history.vol.offset, + "data": "", + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_Application", + "address": command_history.Application.vol.offset, + "data": command_history.get_application(), + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_ProcessHandle", + "address": command_history.ConsoleProcessHandle.ProcessHandle.vol.offset, + "data": hex( + command_history.ConsoleProcessHandle.ProcessHandle + ), + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_CommandCount", + "address": None, + "data": command_history.CommandCount, + } + ) + for ( + cmd_index, + bucket_cmd, + ) in command_history.get_commands(): + try: + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_Command_{cmd_index}", + "address": bucket_cmd.vol.offset, + "data": bucket_cmd.get_command(), + } + ) + except Exception as e: + vollog.debug( + f"reading {bucket_cmd} encountered exception {e}" + ) + except Exception as e: + vollog.debug( + f"reading {command_history} encountered exception {e}" + ) + + vollog.debug(f"Getting ScreenBuffer entries for {console_info}") + for screen_index, screen_info in enumerate( + console_info.get_screens() + ): + try: + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}", + "address": screen_info, + "data": "", + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenX", + "address": None, + "data": screen_info.ScreenX, + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenY", + "address": None, + "data": screen_info.ScreenY, + } + ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.Dump", + "address": None, + "data": "\n".join(screen_info.get_buffer()), + } + ) + except Exception as e: + vollog.debug( + f"reading {screen_info} encountered exception {e}" + ) + + except exceptions.PagedInvalidAddressException as exp: + vollog.debug( + f"Required memory at {exp.invalid_address:#x} is not valid" + ) + + yield conhost_proc, console_info, console_properties + + @classmethod + def get_console_settings_from_registry( + cls, + context: interfaces.context.ContextInterface, + config_path: str, + kernel_layer_name: str, + kernel_symbol_table_name: str, + max_history: Set[int], + max_buffers: Set[int], + ) -> Tuple[Set[int], Set[int]]: + """ + Walks the Registry user hives and extracts any CommandHistorySize and HistoryBufferMax values + for scanning + + Args: + context: The context to retrieve required elements (layers, symbol tables) from + config_path: The config path where to find symbol files + kernel_layer_name: The name of the layer on which to operate + kernel_symbol_table_name: The name of the table containing the kernel symbols + max_history: an initial set of CommandHistorySize values + max_buffers: an initial list of HistoryBufferMax values + + Returns: + The updated max_history and max_buffers sets. + """ + vollog.debug( + f"Possible CommandHistorySize values before checking Registry: {max_history}" + ) + vollog.debug( + f"Possible HistoryBufferMax values before checking Registry: {max_buffers}" + ) + + for hive in hivelist.HiveList.list_hives( + context=context, + base_config_path=config_path, + layer_name=kernel_layer_name, + symbol_table=kernel_symbol_table_name, + hive_offsets=None, + ): + try: + for value in hive.get_key("Console").get_values(): + val_name = str(value.get_name()) + if val_name == "HistoryBufferSize": + max_history.add(value.decode_data()) + elif val_name == "NumberOfHistoryBuffers": + max_buffers.add(value.decode_data()) + except: + continue + + return max_history, max_buffers + + def _generator( + self, procs: Generator[interfaces.objects.ObjectInterface, None, None] + ): + """ + Generates the console information to use in rendering + + Args: + procs: the process list filtered to conhost.exe instances + """ + + kernel = self.context.modules[self.config["kernel"]] + + max_history = set(self.config.get("max_history", [50])) + max_buffers = set(self.config.get("max_buffers", [4])) + no_registry = self.config.get("no_registry") + + if no_registry is False: + max_history, max_buffers = self.get_console_settings_from_registry( + self.context, + self.config_path, + kernel.layer_name, + kernel.symbol_table_name, + max_history, + max_buffers, + ) + + vollog.debug(f"Possible CommandHistorySize values: {max_history}") + vollog.debug(f"Possible HistoryBufferMax values: {max_buffers}") + + for proc, console_info, console_properties in self.get_console_info( + self.context, + kernel.layer_name, + kernel.symbol_table_name, + self.config_path, + procs, + max_history, + max_buffers, + ): + process_name = utility.array_to_string(proc.ImageFileName) + + if console_info and console_properties: + for console_property in console_properties: + yield ( + 0, + ( + proc.UniqueProcessId, + process_name, + format_hints.Hex(console_info.vol.offset), + console_property["name"], + ( + renderers.NotApplicableValue() + if console_property["address"] is None + else format_hints.Hex(console_property["address"]) + ), + str(console_property["data"]), + ), + ) + + def _conhost_proc_filter(self, proc): + """ + Used to filter to only conhost.exe processes + """ + process_name = utility.array_to_string(proc.ImageFileName) + + return process_name != "conhost.exe" + + def run(self): + kernel = self.context.modules[self.config["kernel"]] + + return renderers.TreeGrid( + [ + ("PID", int), + ("Process", str), + ("ConsoleInfo", format_hints.Hex), + ("Property", str), + ("Address", format_hints.Hex), + ("Data", str), + ], + self._generator( + pslist.PsList.list_processes( + context=self.context, + layer_name=kernel.layer_name, + symbol_table=kernel.symbol_table_name, + filter_func=self._conhost_proc_filter, + ) + ), + ) diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json new file mode 100644 index 000000000..3ae41fdd7 --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json @@ -0,0 +1,595 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 24 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 26 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 136 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 140 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1616 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1552 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1680 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1296 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1272 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1280 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 9176 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 9184 + }, + "ExeAliasList": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 9232 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 20 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "BufferDeque": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_DEQUE" + } + }, + "offset": 0 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "name": "void", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 16 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 40 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 48 + }, + "BufferEnd": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 54 + }, + "BufferLastIndex": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 56 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 96 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 8 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 64 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 88 + } }, + "kind": "struct", + "size": 96 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json new file mode 100644 index 000000000..b74862598 --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json @@ -0,0 +1,595 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 24 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 26 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 136 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 140 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1616 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1552 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1680 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1296 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1272 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1280 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -288 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -280 + }, + "ExeAliasList": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -376 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 20 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "BufferDeque": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_DEQUE" + } + }, + "offset": 0 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "name": "void", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 16 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 40 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 48 + }, + "BufferEnd": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 54 + }, + "BufferLastIndex": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 56 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 96 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 8 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 64 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 88 + } }, + "kind": "struct", + "size": 96 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py new file mode 100644 index 000000000..2db1f4cad --- /dev/null +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -0,0 +1,303 @@ +# This file is Copyright 2024 Volatility Foundation and licensed under the Volatility Software License 1.0 +# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 +# + +from volatility3.framework import objects +from volatility3.framework import constants + + +class ROW(objects.StructType): + """A Row Structure.""" + + def _valid_dbcs(self, c): + # TODO this need more research and testing + # https://github.com/search?q=repo%3Amicrosoft%2Fterminal+DbcsAttr&type=code + valid = c in ( + 0x0, + 0x1, + 0x2, + 0x20, + 0x28, + 0x30, + 0x48, + 0x60, + 0x80, + 0xF8, + 0xF0, + 0xA0, + ) + # if not valid: + # print("Bad Dbcs Attribute {}".format(hex(c))) + return valid + + def get_text(self, truncate=True): + """A convenience method to extract the text from the _ROW. The _ROW + contains a pointer CharRow to an array of CharRowCell objects. Each + CharRowCell contains the wide character and an attribute. Enumerating + self.CharRow.Chars and casting each character to unicode takes too long, + so this reads the whole row into a buffer, then extracts the text characters.""" + + layer = self._context.layers[self.vol.layer_name] + offset = self.CharRow.Chars.vol.offset + length = self.RowLength * 3 + char_row = layer.read(offset, length) + line = "" + try: + if char_row: + line = "".join( + # "{} {} =".format(char_row[i:i + 2].decode('utf-16le', errors='replace'), char_row[i+2]) if self._valid_dbcs(char_row[i+2]) else "" + ( + char_row[i : i + 2].decode("utf-16le", errors="replace") + if self._valid_dbcs(char_row[i + 2]) + else "" + ) + for i in range(0, len(char_row), 3) + ) + except Exception as e: + print(e) + line = "" + + if truncate: + return line.rstrip() + else: + return line + + +class SCREEN_INFORMATION(objects.StructType): + """A Screen Information Structure.""" + + @property + def ScreenX(self): + return self.TextBufferInfo.BufferRows.Rows[0].Row.RowLength2 + + @property + def ScreenY(self): + return self.TextBufferInfo.BufferCapacity + + def _truncate_rows(self, rows): + """To truncate empty rows at the end, walk the list + backwards and get the last non-empty row. Use that + row index to splice. Rows are created based on the + length given in the ROW structure, so empty rows will + be ''.""" + + non_empty_index = 0 + rows_traversed = False + + for index, row in enumerate(reversed(rows)): + # the string was created based on the length in the ROW structure so it shouldn't have any bad data + if len(row.rstrip()) > 0: + non_empty_index = index + break + rows_traversed = True + + if non_empty_index == 0 and rows_traversed: + rows = [] + else: + rows = rows[0 : len(rows) - non_empty_index] + + return rows + + def get_buffer(self, truncate_rows=True, truncate_lines=True): + """Get the screen buffer. + + The screen buffer is comprised of the screen's Y + coordinate which tells us the number of rows and + the X coordinate which tells us the width of each + row in characters. Windows 10 17763 changed from + a large text buffer to a grid of cells, with each + cell containing a single wide character in that + cell, stored in a CharRowCell object. + + @param truncate: True if the empty rows at the + end (i.e. bottom) of the screen buffer should be + supressed. + """ + rows = [] + + capacity = self.TextBufferInfo.BufferCapacity + start = self.TextBufferInfo.BufferStart + buffer_rows = self.TextBufferInfo.BufferRows.dereference() + buffer_rows.Rows.count = self.TextBufferInfo.BufferCapacity + + for i in range(capacity): + index = (start + i) % capacity + row = buffer_rows.Rows[index].Row + try: + text = row.get_text(truncate_lines) + rows.append(text) + except: + break + + if truncate_rows: + rows = self._truncate_rows(rows) + + if rows: + rows = ["=== Start of buffer ==="] + rows + ["=== End of buffer ==="] + else: + rows = ["=== No buffer data found ==="] + return rows + + +class CONSOLE_INFORMATION(objects.StructType): + """A Console Information Structure.""" + + @property + def ScreenBuffer(self): + return self.GetScreenBuffer + + def is_valid(self, max_buffers=4) -> bool: + """Determine if the structure is valid.""" + + # Last displayed must be between -1 and max + if self.HistoryBufferCount < 1 or self.HistoryBufferCount > max_buffers: + return False + + if not self.get_title() and not self.get_original_title(): + return False + + return True + + def get_screens(self): + """Generator for screens in the console. + + A console can have multiple screen buffers at a time, + but only the current/active one is displayed. + + Multiple screens are tracked using the singly-linked + list _SCREEN_INFORMATION.Next. + + See CreateConsoleScreenBuffer + """ + screens = [self.CurrentScreenBuffer] + + if self.ScreenBuffer not in screens: + screens.append(self.ScreenBuffer) + + seen = set() + + for screen in screens: + cur = screen + while cur and cur.vol.offset != 0 and cur.vol.offset not in seen: + cur.TextBufferInfo.BufferRows.Rows.count = ( + cur.TextBufferInfo.BufferCapacity + ) + yield cur + seen.add(cur.vol.offset) + cur = cur.Next + + def get_histories(self): + for cmd_hist in self.HistoryList.dereference().to_list( + f"{self.get_symbol_table_name()}{constants.BANG}_COMMAND_HISTORY", + "ListEntry", + ): + yield cmd_hist + + def get_processes(self): + for proc in self.ConsoleProcessList.dereference().to_list( + f"{self.get_symbol_table_name()}{constants.BANG}_CONSOLE_PROCESS_LIST", + "ListEntry", + ): + yield proc + + def get_title(self): + try: + return self.Title.dereference().cast( + "string", encoding="utf-16", errors="replace", max_length=512 + ) + except: + return "" + + def get_original_title(self): + try: + return self.OriginalTitle.dereference().cast( + "string", encoding="utf-16", errors="replace", max_length=512 + ) + except: + return "" + + +class COMMAND(objects.StructType): + """A Command Structure""" + + def get_command(self): + if self.Length < 8: + return self.Chars.cast( + "string", + encoding="utf-16", + errors="replace", + max_length=self.Length * 2, + ) + elif self.Length < 1024: + return self.Pointer.dereference().cast( + "string", encoding="utf-16", errors="replace", max_length=512 + ) + + +class COMMAND_HISTORY(objects.StructType): + """A Command History Structure.""" + + @property + def CommandCount(self): + command_type = self.get_symbol_table_name() + constants.BANG + "_COMMAND" + command_size = self._context.symbol_space.get_type(command_type).size + return int((self.CommandBucket.End - self.CommandBucket.Begin) / command_size) + + def get_application(self): + if self.Application.Length < 8: + return self.Application.Chars.cast( + "string", + encoding="utf-16", + errors="replace", + max_length=self.Application.Length * 2, + ) + elif self.Application.Length < 1024: + return self.Application.Pointer.dereference().cast( + "string", encoding="utf-16", errors="replace", max_length=512 + ) + + def scan_command_bucket(self, end=None): + """Brute force print all strings pointed to by the CommandBucket entries by + going to greater of EndCapacity or CommandCountMax*sizeof(_COMMAND)""" + + command_type = self.get_symbol_table_name() + constants.BANG + "_COMMAND" + command_history_size = self._context.symbol_space.get_type( + self.vol.type_name + ).size + command_size = self._context.symbol_space.get_type(command_type).size + if end is None: + end = max( + self.CommandBucket.EndCapacity, + self.CommandBucket.Begin + command_history_size * self.CommandCountMax, + ) + + for i, pointer in enumerate(range(self.CommandBucket.Begin, end, command_size)): + yield i, self._context.object(command_type, self.vol.layer_name, pointer) + + def get_commands(self): + """Generator for commands in the history buffer. + + The CommandBucket is an array of pointers to _COMMAND + structures. The array size is CommandCount. Once CommandCount + is reached, the oldest commands are cycled out and the + rest are coalesced. + """ + + for i, cmd in self.scan_command_bucket(self.CommandBucket.End): + yield i, cmd + + +win10_x64_class_types = { + "_ROW": ROW, + "_SCREEN_INFORMATION": SCREEN_INFORMATION, + "_CONSOLE_INFORMATION": CONSOLE_INFORMATION, + "_COMMAND_HISTORY": COMMAND_HISTORY, + "_COMMAND": COMMAND, +} +class_types = { + "_ROW": ROW, + "_SCREEN_INFORMATION": SCREEN_INFORMATION, + "_CONSOLE_INFORMATION": CONSOLE_INFORMATION, + "_COMMAND_HISTORY": COMMAND_HISTORY, + "_COMMAND": COMMAND, +} From fdb131f870f5a3ef97dfe5f33e3ee05cf17d83f2 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Thu, 1 Aug 2024 16:27:48 -0500 Subject: [PATCH 02/17] #816 - add cmdscan and bug fixes --- .../framework/plugins/windows/cmdscan.py | 327 ++++++++++++++++++ .../framework/plugins/windows/consoles.py | 2 +- .../consoles-win10-20348-2461-x64.json | 2 +- .../consoles/consoles-win10-20348-x64.json | 2 +- .../symbols/windows/extensions/consoles.py | 31 +- 5 files changed, 360 insertions(+), 4 deletions(-) create mode 100644 volatility3/framework/plugins/windows/cmdscan.py diff --git a/volatility3/framework/plugins/windows/cmdscan.py b/volatility3/framework/plugins/windows/cmdscan.py new file mode 100644 index 000000000..86a34a4f8 --- /dev/null +++ b/volatility3/framework/plugins/windows/cmdscan.py @@ -0,0 +1,327 @@ +# This file is Copyright 2024 Volatility Foundation and licensed under the Volatility Software License 1.0 +# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 +# + +# This module attempts to locate windows console histories. + +import logging +import struct +from typing import Tuple, Generator, Set, Dict, Any, List, Optional + +from volatility3.framework import interfaces +from volatility3.framework import renderers +from volatility3.framework.configuration import requirements +from volatility3.framework.layers import scanners +from volatility3.framework.objects import utility +from volatility3.framework.renderers import format_hints +from volatility3.plugins.windows import pslist, vadinfo, info, verinfo, consoles +from volatility3.plugins.windows.registry import hivelist + + +try: + import capstone + + has_capstone = True +except ImportError: + has_capstone = False + +vollog = logging.getLogger(__name__) + + +class CmdScan(interfaces.plugins.PluginInterface): + """Looks for Windows Command History lists""" + + _required_framework_version = (2, 4, 0) + + @classmethod + def get_requirements(cls): + # 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="pslist", component=pslist.PsList, version=(2, 0, 0) + ), + requirements.PluginRequirement( + name="hivelist", plugin=hivelist.HiveList, version=(1, 0, 0) + ), + requirements.BooleanRequirement( + name="no_registry", + description="Don't search the registry for possible values of CommandHistorySize", + optional=True, + default=False, + ), + requirements.ListRequirement( + name="max_history", + element_type=int, + description="CommandHistorySize values to search for.", + optional=True, + default=[50], + ), + ] + + @classmethod + def get_filtered_vads( + cls, conhost_proc: interfaces.context.ContextInterface, size_filter: Optional[int]=0x40000000 + ) -> List[Tuple[int, int]]: + """ + Returns vads of a process with smaller than size_filter + + Args: + conhost_proc: the process object for conhost.exe + + Returns: + A list of tuples of: + vad_base: the base address + vad_size: the size of the VAD + """ + vads = [] + for vad in conhost_proc.get_vad_root().traverse(): + base = vad.get_start() + if vad.get_size() < size_filter: + vads.append((base, vad.get_size())) + + return vads + + @classmethod + def get_command_history( + cls, + context: interfaces.context.ContextInterface, + kernel_layer_name: str, + kernel_table_name: str, + config_path: str, + procs: Generator[interfaces.objects.ObjectInterface, None, None], + max_history: Set[int], + ) -> Tuple[ + interfaces.context.ContextInterface, + interfaces.context.ContextInterface, + Dict[str, Any], + ]: + """Gets the list of commands from each Command History structure + + Args: + context: The context to retrieve required elements (layers, symbol tables) from + kernel_layer_name: The name of the layer on which to operate + kernel_table_name: The name of the table containing the kernel symbols + config_path: The config path where to find symbol files + procs: list of process objects + max_history: an initial set of CommandHistorySize values + + Returns: + The conhost process object, the command history structure, a dictionary of properties for + that command historyn structure. + """ + + conhost_symbol_table = consoles.Consoles.create_conhost_symbol_table( + context, kernel_layer_name, kernel_table_name, config_path + ) + + for conhost_proc, proc_layer_name in consoles.Consoles.find_conhost_proc(procs): + if not conhost_proc: + vollog.info( + "Unable to find a valid conhost.exe process in the process list. Analysis cannot proceed." + ) + continue + vollog.debug( + f"Found conhost process {conhost_proc} with pid {conhost_proc.UniqueProcessId}" + ) + + conhostexe_base, conhostexe_size = consoles.Consoles.find_conhostexe(conhost_proc) + if not conhostexe_base: + vollog.info( + "Unable to find the location of conhost.exe. Analysis cannot proceed." + ) + continue + vollog.debug(f"Found conhost.exe base at {conhostexe_base:#x}") + + proc_layer = context.layers[proc_layer_name] + + conhost_module = context.module( + conhost_symbol_table, proc_layer_name, offset=conhostexe_base + ) + + sections = cls.get_filtered_vads(conhost_proc) + # scan for potential _COMMAND_HISTORY structures by using the CommandHistorySize + for max_history_value in max_history: + max_history_bytes = struct.pack("H", max_history_value) + vollog.debug( + f"Scanning for CommandHistorySize value: {max_history_bytes}" + ) + for address in proc_layer.scan( + context, + scanners.BytesScanner(max_history_bytes), + sections=sections, + ): + command_history_properties = [] + + try: + command_history = conhost_module.object( + "_COMMAND_HISTORY", + offset=address + - conhost_module.get_type( + "_COMMAND_HISTORY" + ).relative_child_offset("CommandCountMax"), + absolute=True, + ) + + if not command_history.is_valid(max_history_value): + continue + + vollog.debug( + f"Getting Command History properties for {command_history}" + ) + command_history_properties.append( + { + "name": f"_COMMAND_HISTORY.Application", + "address": command_history.Application.vol.offset, + "data": command_history.get_application(), + } + ) + command_history_properties.append( + { + "name": f"_COMMAND_HISTORY.ProcessHandle", + "address": command_history.ConsoleProcessHandle.ProcessHandle.vol.offset, + "data": hex( + command_history.ConsoleProcessHandle.ProcessHandle + ), + } + ) + command_history_properties.append( + { + "name": f"_COMMAND_HISTORY.CommandCount", + "address": None, + "data": command_history.CommandCount, + } + ) + command_history_properties.append( + { + "name": f"_COMMAND_HISTORY.LastDisplayed", + "address": command_history.LastDisplayed.vol.offset, + "data": command_history.LastDisplayed, + } + ) + command_history_properties.append( + { + "name": f"_COMMAND_HISTORY.CommandCountMax", + "address": command_history.CommandCountMax.vol.offset, + "data": command_history.CommandCountMax, + } + ) + + command_history_properties.append( + { + "name": f"_COMMAND_HISTORY.CommandBucket", + "address": command_history.CommandBucket.vol.offset, + "data": "", + } + ) + for ( + cmd_index, + bucket_cmd, + ) in command_history.scan_command_bucket(): + try: + command_history_properties.append( + { + "name": f"_COMMAND_HISTORY.CommandBucket_Command_{cmd_index}", + "address": bucket_cmd.vol.offset, + "data": bucket_cmd.get_command(), + } + ) + except Exception as e: + vollog.debug( + f"reading {bucket_cmd} encountered exception {e}" + ) + except Exception as e: + vollog.debug( + f"reading {command_history} encountered exception {e}" + ) + + yield conhost_proc, command_history, command_history_properties + + def _generator( + self, procs: Generator[interfaces.objects.ObjectInterface, None, None] + ): + """ + Generates the command history to use in rendering + + Args: + procs: the process list filtered to conhost.exe instances + """ + + kernel = self.context.modules[self.config["kernel"]] + + max_history = set(self.config.get("max_history", [50])) + no_registry = self.config.get("no_registry") + + if no_registry is False: + max_history, _max_buffers = consoles.Consoles.get_console_settings_from_registry( + self.context, + self.config_path, + kernel.layer_name, + kernel.symbol_table_name, + max_history, + [], + ) + + vollog.debug(f"Possible CommandHistorySize values: {max_history}") + + for proc, command_history, command_history_properties in self.get_command_history( + self.context, + kernel.layer_name, + kernel.symbol_table_name, + self.config_path, + procs, + max_history, + ): + process_name = utility.array_to_string(proc.ImageFileName) + + if command_history and command_history_properties: + for command_history_property in command_history_properties: + yield ( + 0, + ( + proc.UniqueProcessId, + process_name, + format_hints.Hex(command_history.vol.offset), + command_history_property["name"], + ( + renderers.NotApplicableValue() + if command_history_property["address"] is None + else format_hints.Hex(command_history_property["address"]) + ), + str(command_history_property["data"]), + ), + ) + + def _conhost_proc_filter(self, proc): + """ + Used to filter to only conhost.exe processes + """ + process_name = utility.array_to_string(proc.ImageFileName) + + return process_name != "conhost.exe" + + def run(self): + kernel = self.context.modules[self.config["kernel"]] + + return renderers.TreeGrid( + [ + ("PID", int), + ("Process", str), + ("ConsoleInfo", format_hints.Hex), + ("Property", str), + ("Address", format_hints.Hex), + ("Data", str), + ], + self._generator( + pslist.PsList.list_processes( + context=self.context, + layer_name=kernel.layer_name, + symbol_table=kernel.symbol_table_name, + filter_func=self._conhost_proc_filter, + ) + ), + ) diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index f6bbb3ae7..509b6ae9d 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -363,7 +363,7 @@ class Consoles(interfaces.plugins.PluginInterface): interfaces.context.ContextInterface, Dict[str, Any], ]: - """Extracts the cmdline from PEB + """Gets the Console Information structure and its related properties for each conhost process Args: context: The context to retrieve required elements (layers, symbol tables) from diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json index 3ae41fdd7..a4adf8028 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json @@ -232,7 +232,7 @@ "kind": "base", "name": "unsigned int" }, - "offset": 20 + "offset": 24 } }, "kind": "struct", diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json index b74862598..5cc7ab6f5 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json @@ -232,7 +232,7 @@ "kind": "base", "name": "unsigned int" }, - "offset": 20 + "offset": 24 } }, "kind": "struct", diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 2db1f4cad..279ee723e 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -220,6 +220,12 @@ class CONSOLE_INFORMATION(objects.StructType): class COMMAND(objects.StructType): """A Command Structure""" + def is_valid(self): + if self.Length < 1 or self.Allocated < 1 or self.Length > 1024 or self.Allocated > 1024: + return False + + return True + def get_command(self): if self.Length < 8: return self.Chars.cast( @@ -243,6 +249,26 @@ class COMMAND_HISTORY(objects.StructType): command_size = self._context.symbol_space.get_type(command_type).size return int((self.CommandBucket.End - self.CommandBucket.Begin) / command_size) + @property + def ProcessHandle(self): + """ Allow ProcessHandle to be referenced regardless of OS version """ + return self.ConsoleProcessHandle.ProcessHandle + + def is_valid(self, max_history=50): + # The count must be between zero and max + if self.CommandCount < 0 or self.CommandCount > max_history: + return False + + # Last displayed must be between -1 and max + if self.LastDisplayed < -1 or self.LastDisplayed > max_history: + return False + + # Process handle must be a valid pid + if self.ProcessHandle <= 0 or self.ProcessHandle > 0xFFFF or self.ProcessHandle % 4 != 0: + return False + + return True + def get_application(self): if self.Application.Length < 8: return self.Application.Chars.cast( @@ -265,6 +291,7 @@ class COMMAND_HISTORY(objects.StructType): self.vol.type_name ).size command_size = self._context.symbol_space.get_type(command_type).size + if end is None: end = max( self.CommandBucket.EndCapacity, @@ -272,7 +299,9 @@ class COMMAND_HISTORY(objects.StructType): ) for i, pointer in enumerate(range(self.CommandBucket.Begin, end, command_size)): - yield i, self._context.object(command_type, self.vol.layer_name, pointer) + cmd = self._context.object(command_type, self.vol.layer_name, pointer) + if cmd.is_valid(): + yield i, cmd def get_commands(self): """Generator for commands in the history buffer. From a515e571dcb9eef2fc268b707cc175951f0831b8 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Sat, 3 Aug 2024 12:03:20 -0700 Subject: [PATCH 03/17] add Win10x64 17763 --- .../framework/plugins/windows/consoles.py | 8 + .../consoles/consoles-win10-17763-x64.json | 595 ++++++++++++++++++ .../symbols/windows/extensions/consoles.py | 5 + 3 files changed, 608 insertions(+) create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index 509b6ae9d..0ef9e990a 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -203,6 +203,7 @@ class Consoles(interfaces.plugins.PluginInterface): version_dict = {} else: version_dict = { + (10, 0, 17763, 0): "consoles-win10-17763-x64", (10, 0, 20348, 1): "consoles-win10-20348-x64", (10, 0, 20348, 1970): "consoles-win10-20348-1970-x64", (10, 0, 20348, 2461): "consoles-win10-20348-2461-x64", @@ -580,6 +581,13 @@ class Consoles(interfaces.plugins.PluginInterface): "data": command_history.CommandCount, } ) + console_properties.append( + { + "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_LastDisplayed", + "address": command_history.LastDisplayed.vol.offset, + "data": command_history.LastDisplayed, + } + ) for ( cmd_index, bucket_cmd, diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json new file mode 100644 index 000000000..f11fb39b1 --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json @@ -0,0 +1,595 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 34 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 144 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 148 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1736 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1672 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1800 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1384 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1360 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1368 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -760 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -752 + }, + "ExeAliasList": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1392 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 32 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 36 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "BufferDeque": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_DEQUE" + } + }, + "offset": 0 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "name": "void", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 8 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 48 + }, + "BufferEnd": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 56 + }, + "BufferLastIndex": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 58 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 112 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 8 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 64 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 88 + } }, + "kind": "struct", + "size": 96 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 279ee723e..74ea80e84 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -20,8 +20,13 @@ class ROW(objects.StructType): 0x28, 0x30, 0x48, + 0x50, 0x60, 0x80, + 0xa8, + 0xc0, + 0xc8, + 0x98, 0xF8, 0xF0, 0xA0, From 583cffe960a65a136d80bab194765368220bd9bf Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Sat, 3 Aug 2024 14:24:17 -0700 Subject: [PATCH 04/17] #816 - next console properties for better readability in treegrid --- .../framework/plugins/windows/cmdscan.py | 17 ++++++- .../framework/plugins/windows/consoles.py | 44 +++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/volatility3/framework/plugins/windows/cmdscan.py b/volatility3/framework/plugins/windows/cmdscan.py index 86a34a4f8..1e435c56f 100644 --- a/volatility3/framework/plugins/windows/cmdscan.py +++ b/volatility3/framework/plugins/windows/cmdscan.py @@ -175,6 +175,15 @@ class CmdScan(interfaces.plugins.PluginInterface): ) command_history_properties.append( { + "level": 0, + "name": "_COMMAND_HISTORY", + "address": command_history.vol.offset, + "data": "", + } + ) + command_history_properties.append( + { + "level": 1, "name": f"_COMMAND_HISTORY.Application", "address": command_history.Application.vol.offset, "data": command_history.get_application(), @@ -182,6 +191,7 @@ class CmdScan(interfaces.plugins.PluginInterface): ) command_history_properties.append( { + "level": 1, "name": f"_COMMAND_HISTORY.ProcessHandle", "address": command_history.ConsoleProcessHandle.ProcessHandle.vol.offset, "data": hex( @@ -191,6 +201,7 @@ class CmdScan(interfaces.plugins.PluginInterface): ) command_history_properties.append( { + "level": 1, "name": f"_COMMAND_HISTORY.CommandCount", "address": None, "data": command_history.CommandCount, @@ -198,6 +209,7 @@ class CmdScan(interfaces.plugins.PluginInterface): ) command_history_properties.append( { + "level": 1, "name": f"_COMMAND_HISTORY.LastDisplayed", "address": command_history.LastDisplayed.vol.offset, "data": command_history.LastDisplayed, @@ -205,6 +217,7 @@ class CmdScan(interfaces.plugins.PluginInterface): ) command_history_properties.append( { + "level": 1, "name": f"_COMMAND_HISTORY.CommandCountMax", "address": command_history.CommandCountMax.vol.offset, "data": command_history.CommandCountMax, @@ -213,6 +226,7 @@ class CmdScan(interfaces.plugins.PluginInterface): command_history_properties.append( { + "level": 1, "name": f"_COMMAND_HISTORY.CommandBucket", "address": command_history.CommandBucket.vol.offset, "data": "", @@ -225,6 +239,7 @@ class CmdScan(interfaces.plugins.PluginInterface): try: command_history_properties.append( { + "level": 2, "name": f"_COMMAND_HISTORY.CommandBucket_Command_{cmd_index}", "address": bucket_cmd.vol.offset, "data": bucket_cmd.get_command(), @@ -281,7 +296,7 @@ class CmdScan(interfaces.plugins.PluginInterface): if command_history and command_history_properties: for command_history_property in command_history_properties: yield ( - 0, + command_history_property["level"], ( proc.UniqueProcessId, process_name, diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index 0ef9e990a..3b87734e7 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -445,6 +445,15 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 0, + "name": "_CONSOLE_INFORMATION", + "address": console_info.vol.offset, + "data": "", + } + ) + console_properties.append( + { + "level": 1, "name": "_CONSOLE_INFORMATION.ScreenX", "address": console_info.ScreenX.vol.offset, "data": console_info.ScreenX, @@ -452,6 +461,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.ScreenY", "address": console_info.ScreenY.vol.offset, "data": console_info.ScreenY, @@ -459,6 +469,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.CommandHistorySize", "address": console_info.CommandHistorySize.vol.offset, "data": console_info.CommandHistorySize, @@ -466,6 +477,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.HistoryBufferCount", "address": console_info.HistoryBufferCount.vol.offset, "data": console_info.HistoryBufferCount, @@ -473,6 +485,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.HistoryBufferMax", "address": console_info.HistoryBufferMax.vol.offset, "data": console_info.HistoryBufferMax, @@ -480,6 +493,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.Title", "address": console_info.Title.vol.offset, "data": console_info.get_title(), @@ -487,6 +501,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.OriginalTitle", "address": console_info.OriginalTitle.vol.offset, "data": console_info.get_original_title(), @@ -498,6 +513,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.ProcessCount", "address": console_info.ProcessCount.vol.offset, "data": console_info.ProcessCount, @@ -505,6 +521,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.ConsoleProcessList", "address": console_info.ConsoleProcessList.vol.offset, "data": "", @@ -515,6 +532,7 @@ class Consoles(interfaces.plugins.PluginInterface): ): console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.ConsoleProcessList.ConsoleProcess_{index}", "address": attached_proc.ConsoleProcess.dereference().vol.offset, "data": "", @@ -522,6 +540,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.ConsoleProcessList.ConsoleProcess_{index}_ProcessId", "address": attached_proc.ConsoleProcess.ProcessId.vol.offset, "data": attached_proc.ConsoleProcess.ProcessId, @@ -529,6 +548,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.ConsoleProcessList.ConsoleProcess_{index}_ProcessHandle", "address": attached_proc.ConsoleProcess.ProcessHandle.vol.offset, "data": hex( @@ -542,6 +562,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 1, "name": "_CONSOLE_INFORMATION.HistoryList", "address": console_info.HistoryList.vol.offset, "data": "", @@ -553,6 +574,7 @@ class Consoles(interfaces.plugins.PluginInterface): try: console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}", "address": command_history.vol.offset, "data": "", @@ -560,6 +582,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_Application", "address": command_history.Application.vol.offset, "data": command_history.get_application(), @@ -567,6 +590,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_ProcessHandle", "address": command_history.ConsoleProcessHandle.ProcessHandle.vol.offset, "data": hex( @@ -576,6 +600,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_CommandCount", "address": None, "data": command_history.CommandCount, @@ -583,6 +608,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_LastDisplayed", "address": command_history.LastDisplayed.vol.offset, "data": command_history.LastDisplayed, @@ -593,8 +619,8 @@ class Consoles(interfaces.plugins.PluginInterface): bucket_cmd, ) in command_history.get_commands(): try: - console_properties.append( - { + console_properties.append({ + "level": 3, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_Command_{cmd_index}", "address": bucket_cmd.vol.offset, "data": bucket_cmd.get_command(), @@ -610,12 +636,21 @@ class Consoles(interfaces.plugins.PluginInterface): ) vollog.debug(f"Getting ScreenBuffer entries for {console_info}") + console_properties.append( + { + "level": 1, + "name": "_CONSOLE_INFORMATION.CurrentScreenBuffer", + "address": console_info.CurrentScreenBuffer.vol.offset, + "data": "", + } + ) for screen_index, screen_info in enumerate( console_info.get_screens() ): try: console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}", "address": screen_info, "data": "", @@ -623,6 +658,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenX", "address": None, "data": screen_info.ScreenX, @@ -630,6 +666,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenY", "address": None, "data": screen_info.ScreenY, @@ -637,6 +674,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) console_properties.append( { + "level": 2, "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.Dump", "address": None, "data": "\n".join(screen_info.get_buffer()), @@ -748,7 +786,7 @@ class Consoles(interfaces.plugins.PluginInterface): if console_info and console_properties: for console_property in console_properties: yield ( - 0, + console_property["level"], ( proc.UniqueProcessId, process_name, From a3c50e8221ed39e399b500376cb448019f9403db Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Sat, 3 Aug 2024 14:27:42 -0700 Subject: [PATCH 05/17] #816 - black fixes --- .../framework/plugins/windows/consoles.py | 3 ++- .../symbols/windows/extensions/consoles.py | 21 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index 3b87734e7..9b41b2890 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -619,7 +619,8 @@ class Consoles(interfaces.plugins.PluginInterface): bucket_cmd, ) in command_history.get_commands(): try: - console_properties.append({ + console_properties.append( + { "level": 3, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_Command_{cmd_index}", "address": bucket_cmd.vol.offset, diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 74ea80e84..23670bb9b 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -23,9 +23,9 @@ class ROW(objects.StructType): 0x50, 0x60, 0x80, - 0xa8, - 0xc0, - 0xc8, + 0xA8, + 0xC0, + 0xC8, 0x98, 0xF8, 0xF0, @@ -226,7 +226,12 @@ class COMMAND(objects.StructType): """A Command Structure""" def is_valid(self): - if self.Length < 1 or self.Allocated < 1 or self.Length > 1024 or self.Allocated > 1024: + if ( + self.Length < 1 + or self.Allocated < 1 + or self.Length > 1024 + or self.Allocated > 1024 + ): return False return True @@ -256,7 +261,7 @@ class COMMAND_HISTORY(objects.StructType): @property def ProcessHandle(self): - """ Allow ProcessHandle to be referenced regardless of OS version """ + """Allow ProcessHandle to be referenced regardless of OS version""" return self.ConsoleProcessHandle.ProcessHandle def is_valid(self, max_history=50): @@ -269,7 +274,11 @@ class COMMAND_HISTORY(objects.StructType): return False # Process handle must be a valid pid - if self.ProcessHandle <= 0 or self.ProcessHandle > 0xFFFF or self.ProcessHandle % 4 != 0: + if ( + self.ProcessHandle <= 0 + or self.ProcessHandle > 0xFFFF + or self.ProcessHandle % 4 != 0 + ): return False return True From 60f14478e2860cb97ef15954f80ee82202f5935f Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Sat, 3 Aug 2024 14:30:27 -0700 Subject: [PATCH 06/17] #816 - black fixes --- .../framework/plugins/windows/cmdscan.py | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/volatility3/framework/plugins/windows/cmdscan.py b/volatility3/framework/plugins/windows/cmdscan.py index 1e435c56f..b92d7efab 100644 --- a/volatility3/framework/plugins/windows/cmdscan.py +++ b/volatility3/framework/plugins/windows/cmdscan.py @@ -65,7 +65,9 @@ class CmdScan(interfaces.plugins.PluginInterface): @classmethod def get_filtered_vads( - cls, conhost_proc: interfaces.context.ContextInterface, size_filter: Optional[int]=0x40000000 + cls, + conhost_proc: interfaces.context.ContextInterface, + size_filter: Optional[int] = 0x40000000, ) -> List[Tuple[int, int]]: """ Returns vads of a process with smaller than size_filter @@ -129,7 +131,9 @@ class CmdScan(interfaces.plugins.PluginInterface): f"Found conhost process {conhost_proc} with pid {conhost_proc.UniqueProcessId}" ) - conhostexe_base, conhostexe_size = consoles.Consoles.find_conhostexe(conhost_proc) + conhostexe_base, conhostexe_size = consoles.Consoles.find_conhostexe( + conhost_proc + ) if not conhostexe_base: vollog.info( "Unable to find the location of conhost.exe. Analysis cannot proceed." @@ -154,7 +158,7 @@ class CmdScan(interfaces.plugins.PluginInterface): context, scanners.BytesScanner(max_history_bytes), sections=sections, - ): + ): command_history_properties = [] try: @@ -272,18 +276,24 @@ class CmdScan(interfaces.plugins.PluginInterface): no_registry = self.config.get("no_registry") if no_registry is False: - max_history, _max_buffers = consoles.Consoles.get_console_settings_from_registry( - self.context, - self.config_path, - kernel.layer_name, - kernel.symbol_table_name, - max_history, - [], + max_history, _max_buffers = ( + consoles.Consoles.get_console_settings_from_registry( + self.context, + self.config_path, + kernel.layer_name, + kernel.symbol_table_name, + max_history, + [], + ) ) vollog.debug(f"Possible CommandHistorySize values: {max_history}") - for proc, command_history, command_history_properties in self.get_command_history( + for ( + proc, + command_history, + command_history_properties, + ) in self.get_command_history( self.context, kernel.layer_name, kernel.symbol_table_name, @@ -305,7 +315,9 @@ class CmdScan(interfaces.plugins.PluginInterface): ( renderers.NotApplicableValue() if command_history_property["address"] is None - else format_hints.Hex(command_history_property["address"]) + else format_hints.Hex( + command_history_property["address"] + ) ), str(command_history_property["data"]), ), From f8c25176f3cc07e2c0a3688b26166a92f386fb16 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Sun, 4 Aug 2024 09:30:37 -0700 Subject: [PATCH 07/17] #816 - add 17763, 18362, 19041 x64 support --- .../framework/plugins/windows/consoles.py | 15 +- .../consoles-win10-17763-3232-x64.json | 595 ++++++++++++++++++ .../consoles/consoles-win10-18362-x64.json | 585 +++++++++++++++++ .../consoles/consoles-win10-19041-x64.json | 585 +++++++++++++++++ 4 files changed, 1774 insertions(+), 6 deletions(-) create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index 9b41b2890..c9e8522a4 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -174,7 +174,7 @@ class Consoles(interfaces.plugins.PluginInterface): ) except: # unsure what to raise here. Also, it might be useful to add some kind of fallback, - # either to a user-provided version or to another method to determine tcpip.sys's version + # either to a user-provided version or to another method to determine conhost.exe's version raise exceptions.VolatilityException( "Kernel Debug Structure missing VERSION/KUSER structure, unable to determine Windows version!" ) @@ -203,7 +203,10 @@ class Consoles(interfaces.plugins.PluginInterface): version_dict = {} else: version_dict = { - (10, 0, 17763, 0): "consoles-win10-17763-x64", + (10, 0, 17763, 1): "consoles-win10-17763-x64", + (10, 0, 17763, 3232): "consoles-win10-17763-3232-x64", + (10, 0, 18362, 0): "consoles-win10-18362-x64", + (10, 0, 19041, 0): "consoles-win10-19041-x64", (10, 0, 20348, 1): "consoles-win10-20348-x64", (10, 0, 20348, 1970): "consoles-win10-20348-1970-x64", (10, 0, 20348, 2461): "consoles-win10-20348-2461-x64", @@ -280,11 +283,11 @@ class Consoles(interfaces.plugins.PluginInterface): # try to grab the latest supported version of the current image NT version. If that symbol # version does not work, support has to be added manually. current_versions = [ - (nt_maj, nt_min, vers_min, tcpip_ver) - for nt_maj, nt_min, vers_min, tcpip_ver in version_dict + (nt_maj, nt_min, vers_min, conhost_ver) + for nt_maj, nt_min, vers_min, conhost_ver in version_dict if nt_maj == nt_major_version and nt_min == nt_minor_version - and tcpip_ver <= conhost_mod_version + and conhost_ver <= conhost_mod_version ] current_versions.sort() @@ -319,7 +322,7 @@ class Consoles(interfaces.plugins.PluginInterface): nt_symbol_table: str, config_path: str, ) -> str: - """Creates a symbol table for TCP Listeners and TCP/UDP Endpoints. + """Creates a symbol table for conhost structures. Args: context: The context to retrieve required elements (layers, symbol tables) from diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json new file mode 100644 index 000000000..ba17645c4 --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json @@ -0,0 +1,595 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 34 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 144 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 148 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1736 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1672 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1800 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1384 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1360 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1368 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -760 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -752 + }, + "ExeAliasList": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1392 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "BufferDeque": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_DEQUE" + } + }, + "offset": 0 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "name": "void", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 8 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 48 + }, + "BufferEnd": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 56 + }, + "BufferLastIndex": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 58 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 112 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 8 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 64 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 88 + } }, + "kind": "struct", + "size": 96 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json new file mode 100644 index 000000000..3c1fde26e --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json @@ -0,0 +1,585 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 34 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 144 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 148 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1744 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1680 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1808 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1392 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1368 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1376 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -768 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -760 + }, + "ExeAliasList": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1436 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "BufferDeque": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_DEQUE" + } + }, + "offset": 0 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "name": "void", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 8 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "BufferEnd": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 56 + }, + "BufferLastIndex": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 58 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 88 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 8 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 64 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 88 + } }, + "kind": "struct", + "size": 96 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json new file mode 100644 index 000000000..39ca5f0eb --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json @@ -0,0 +1,585 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 34 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 144 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 148 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1752 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1688 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1816 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1392 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1368 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1376 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -352 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -344 + }, + "ExeAliasList": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1436 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "BufferDeque": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_DEQUE" + } + }, + "offset": 0 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "name": "void", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 8 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 32 + }, + "BufferEnd": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 56 + }, + "BufferLastIndex": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 58 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 88 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 8 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 64 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 88 + } }, + "kind": "struct", + "size": 96 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} From 9b9535d8d716599630ab4c09b92b7e331a832d8b Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Sun, 4 Aug 2024 10:14:36 -0700 Subject: [PATCH 08/17] #816 - other 20348 symbols --- .../consoles-win10-20348-1970-x64.json | 595 ++++++++++++++++++ 1 file changed, 595 insertions(+) create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json new file mode 100644 index 000000000..e0935b4be --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json @@ -0,0 +1,595 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 24 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 26 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 136 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 140 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1616 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1552 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1680 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1296 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1272 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1280 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 9320 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 9328 + }, + "ExeAliasList": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2410 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "BufferDeque": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_DEQUE" + } + }, + "offset": 0 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "name": "void", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 16 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 40 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 48 + }, + "BufferEnd": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 54 + }, + "BufferLastIndex": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 56 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 96 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 8 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 64 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 88 + } }, + "kind": "struct", + "size": 96 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} From 1d43eb305d993a1306cc3971333d8a28bfee03af Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Tue, 6 Aug 2024 15:18:49 -0700 Subject: [PATCH 09/17] fix invalid json on all files --- .../symbols/windows/consoles/consoles-win10-17763-3232-x64.json | 1 - .../symbols/windows/consoles/consoles-win10-17763-x64.json | 1 - .../symbols/windows/consoles/consoles-win10-18362-x64.json | 1 - .../symbols/windows/consoles/consoles-win10-19041-x64.json | 1 - .../symbols/windows/consoles/consoles-win10-20348-1970-x64.json | 1 - .../symbols/windows/consoles/consoles-win10-20348-2461-x64.json | 1 - 6 files changed, 6 deletions(-) diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json index ba17645c4..0a8cb5782 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json @@ -434,7 +434,6 @@ "BufferRows": { "type": { "kind": "pointer", - "name": "void", "subtype": { "kind": "struct", "name": "_ROWS_ARRAY" diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json index f11fb39b1..2b98945c9 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json @@ -434,7 +434,6 @@ "BufferRows": { "type": { "kind": "pointer", - "name": "void", "subtype": { "kind": "struct", "name": "_ROWS_ARRAY" diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json index 3c1fde26e..3d76d1cb4 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json @@ -434,7 +434,6 @@ "BufferRows": { "type": { "kind": "pointer", - "name": "void", "subtype": { "kind": "struct", "name": "_ROWS_ARRAY" diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json index 39ca5f0eb..681113b0f 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json @@ -434,7 +434,6 @@ "BufferRows": { "type": { "kind": "pointer", - "name": "void", "subtype": { "kind": "struct", "name": "_ROWS_ARRAY" diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json index e0935b4be..7bc6ae9d1 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json @@ -434,7 +434,6 @@ "BufferRows": { "type": { "kind": "pointer", - "name": "void", "subtype": { "kind": "struct", "name": "_ROWS_ARRAY" diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json index a4adf8028..f612c527a 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json @@ -434,7 +434,6 @@ "BufferRows": { "type": { "kind": "pointer", - "name": "void", "subtype": { "kind": "struct", "name": "_ROWS_ARRAY" From ac08f42cfd9b9f75067c7f0bd9162d15be05c8a2 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Sun, 4 Aug 2024 12:09:59 -0700 Subject: [PATCH 10/17] #816 - fix invalid json --- .../symbols/windows/consoles/consoles-win10-20348-x64.json | 1 - 1 file changed, 1 deletion(-) diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json index 5cc7ab6f5..083a966a0 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json @@ -434,7 +434,6 @@ "BufferRows": { "type": { "kind": "pointer", - "name": "void", "subtype": { "kind": "struct", "name": "_ROWS_ARRAY" From 48d4048b487b665051c8f21a24ff8e77333ee682 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Fri, 27 Sep 2024 10:02:36 -0500 Subject: [PATCH 11/17] #816 - fixes and additional windows versions --- .../framework/plugins/windows/consoles.py | 291 ++++--- .../framework/plugins/windows/verinfo.py | 2 +- .../consoles-win10-17763-3232-x64.json | 71 +- .../consoles/consoles-win10-17763-x64.json | 71 +- .../consoles/consoles-win10-18362-x64.json | 73 +- .../consoles/consoles-win10-19041-x64.json | 73 +- .../consoles-win10-20348-1970-x64.json | 108 ++- .../consoles-win10-20348-2461-x64.json | 108 ++- .../consoles/consoles-win10-20348-x64.json | 108 ++- .../consoles/consoles-win10-22000-x64.json | 722 +++++++++++++++++ .../consoles-win10-22621-3672-x64.json | 722 +++++++++++++++++ .../consoles/consoles-win10-22621-x64.json | 722 +++++++++++++++++ .../consoles/consoles-win10-25398-x64.json | 723 ++++++++++++++++++ .../symbols/windows/extensions/consoles.py | 112 ++- 14 files changed, 3774 insertions(+), 132 deletions(-) create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3672-x64.json create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json create mode 100644 volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index c9e8522a4..46699aa31 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -11,12 +11,13 @@ from typing import Tuple, Generator, Set, Dict, Any, Type from volatility3.framework import interfaces, symbols, exceptions from volatility3.framework import renderers +from volatility3.framework.interfaces import configuration from volatility3.framework.configuration import requirements from volatility3.framework.layers import scanners from volatility3.framework.objects import utility from volatility3.framework.renderers import format_hints from volatility3.framework.symbols import intermed -from volatility3.framework.symbols.windows import pdbutil, versions +from volatility3.framework.symbols.windows import pdbutil from volatility3.framework.symbols.windows.extensions import pe, consoles from volatility3.plugins.windows import pslist, vadinfo, info, verinfo from volatility3.plugins.windows.registry import hivelist @@ -49,6 +50,9 @@ class Consoles(interfaces.plugins.PluginInterface): requirements.VersionRequirement( name="pslist", component=pslist.PsList, version=(2, 0, 0) ), + requirements.VersionRequirement( + name="verinfo", component=verinfo.VerInfo, version=(1, 0, 0) + ), requirements.VersionRequirement( name="pdbutil", component=pdbutil.PDBUtility, version=(1, 0, 0) ), @@ -92,18 +96,19 @@ class Consoles(interfaces.plugins.PluginInterface): """ for proc in proc_list: - try: - proc_id = proc.UniqueProcessId - proc_layer_name = proc.add_process_layer() + if utility.array_to_string(proc.ImageFileName).lower() == "conhost.exe": + try: + proc_id = proc.UniqueProcessId + proc_layer_name = proc.add_process_layer() - yield proc, proc_layer_name + yield proc, proc_layer_name - except exceptions.InvalidAddressException as excp: - vollog.debug( - "Process {}: invalid address {} in layer {}".format( - proc_id, excp.invalid_address, excp.layer_name + except exceptions.InvalidAddressException as excp: + vollog.debug( + "Process {}: invalid address {} in layer {}".format( + proc_id, excp.invalid_address, excp.layer_name + ) ) - ) @classmethod def find_conhostexe( @@ -122,7 +127,6 @@ class Consoles(interfaces.plugins.PluginInterface): """ for vad in conhost_proc.get_vad_root().traverse(): filename = vad.get_file_name() - if isinstance(filename, str) and filename.lower().endswith("conhost.exe"): base = vad.get_start() return base, vad.get_size() @@ -135,6 +139,9 @@ class Consoles(interfaces.plugins.PluginInterface): context: interfaces.context.ContextInterface, layer_name: str, nt_symbol_table: str, + config_path: str, + conhost_layer_name: str, + conhost_base: int, ) -> Tuple[str, Type]: """Tries to determine which symbol filename to use for the image's console information. This is similar to the netstat plugin. @@ -143,6 +150,9 @@ class Consoles(interfaces.plugins.PluginInterface): context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate nt_symbol_table: The name of the table containing the kernel symbols + config_path: The config path where to find symbol files + conhost_layer_name: The name of the conhot process memory layer + conhost_base: the base address of conhost.exe Returns: The filename of the symbol table to use and the associated class types. @@ -150,10 +160,6 @@ class Consoles(interfaces.plugins.PluginInterface): is_64bit = symbols.symbol_table_is_64bit(context, nt_symbol_table) - is_18363_or_later = versions.is_win10_18363_or_later( - context=context, symbol_table=nt_symbol_table - ) - if is_64bit: arch = "x64" else: @@ -211,23 +217,15 @@ class Consoles(interfaces.plugins.PluginInterface): (10, 0, 20348, 1970): "consoles-win10-20348-1970-x64", (10, 0, 20348, 2461): "consoles-win10-20348-2461-x64", (10, 0, 20348, 2520): "consoles-win10-20348-2461-x64", + (10, 0, 22000, 0): "consoles-win10-22000-x64", + (10, 0, 22621, 1): "consoles-win10-22621-x64", + (10, 0, 22621, 3672): "consoles-win10-22621-3672-x64", + (10, 0, 25398, 0): "consoles-win10-22000-x64", } # we do not need to check for conhost's specific FileVersion in every case conhost_mod_version = 0 # keep it 0 as a default - # special use cases - - # Win10_18363 is not recognized by windows.info as 18363 - # because all kernel file headers and debug structures report 18363 as - # "10.0.18362.1198" with the last part being incremented. However, we can use - # os_distinguisher to differentiate between 18362 and 18363 - if vers_minor_version == 18362 and is_18363_or_later: - vollog.debug( - "Detected 18363 data structures: working with 18363 symbol table." - ) - vers_minor_version = 18363 - # we need to define additional version numbers (which are then found via conhost.exe's FileVersion header) in case there is # ambiguity _within_ an OS version. If such a version number (last number of the tuple) is defined for the current OS # we need to inspect conhost.exe's headers to see if we can grab the precise version @@ -240,24 +238,40 @@ class Consoles(interfaces.plugins.PluginInterface): vollog.debug( "Requiring further version inspection due to OS version by checking conhost.exe's FileVersion header" ) - # the following is IntelLayer specific and might need to be adapted to other architectures. - physical_layer_name = context.layers[layer_name].config.get( - "memory_layer", None - ) - if physical_layer_name: - ver = verinfo.VerInfo.find_version_info( - context, physical_layer_name, "CONHOST.EXE" - ) - if ver: - conhost_mod_version = ver[3] - vollog.debug( - "Determined conhost.exe's FileVersion: {}".format( - conhost_mod_version - ) + pe_table_name = intermed.IntermediateSymbolTable.create( + context, + configuration.path_join(config_path, "conhost"), + "windows", + "pe", + class_types=pe.class_types + ) + + try: + (major, minor, product, build) = verinfo.VerInfo.get_version_information( + context, pe_table_name, conhost_layer_name, conhost_base + ) + conhost_mod_version = build + vollog.debug(f"Found conhost.exe version {major}.{minor}.{product}.{build} in {conhost_layer_name} at base {conhost_base:#x}") + except (exceptions.InvalidAddressException, TypeError, AttributeError): + # the following is IntelLayer specific and might need to be adapted to other architectures. + physical_layer_name = context.layers[layer_name].config.get( + "memory_layer", None + ) + if physical_layer_name: + ver = verinfo.VerInfo.find_version_info( + context, physical_layer_name, "CONHOST.EXE" ) - else: - vollog.debug("Could not determine conhost.exe's FileVersion.") + + if ver: + conhost_mod_version = ver[3] + vollog.debug( + "Determined conhost.exe's FileVersion: {}".format( + conhost_mod_version + ) + ) + else: + vollog.debug("Could not determine conhost.exe's FileVersion.") else: vollog.debug( "Unable to retrieve physical memory layer, skipping FileVersion check." @@ -287,6 +301,7 @@ class Consoles(interfaces.plugins.PluginInterface): for nt_maj, nt_min, vers_min, conhost_ver in version_dict if nt_maj == nt_major_version and nt_min == nt_minor_version + and vers_min <= vers_minor_version and conhost_ver <= conhost_mod_version ] current_versions.sort() @@ -321,6 +336,8 @@ class Consoles(interfaces.plugins.PluginInterface): layer_name: str, nt_symbol_table: str, config_path: str, + conhost_layer_name: str, + conhost_base: int, ) -> str: """Creates a symbol table for conhost structures. @@ -339,13 +356,16 @@ class Consoles(interfaces.plugins.PluginInterface): context, layer_name, nt_symbol_table, + config_path, + conhost_layer_name, + conhost_base, ) vollog.debug(f"Using symbol file '{symbol_filename}' and types {class_types}") return intermed.IntermediateSymbolTable.create( context, - config_path, + configuration.path_join(config_path, "conhost"), os.path.join("windows", "consoles"), symbol_filename, class_types=class_types, @@ -383,9 +403,7 @@ class Consoles(interfaces.plugins.PluginInterface): that console information structure. """ - conhost_symbol_table = cls.create_conhost_symbol_table( - context, kernel_layer_name, kernel_table_name, config_path - ) + conhost_symbol_table = None for conhost_proc, proc_layer_name in cls.find_conhost_proc(procs): if not conhost_proc: @@ -407,6 +425,16 @@ class Consoles(interfaces.plugins.PluginInterface): proc_layer = context.layers[proc_layer_name] + if conhost_symbol_table is None: + conhost_symbol_table = cls.create_conhost_symbol_table( + context, + kernel_layer_name, + kernel_table_name, + config_path, + proc_layer_name, + conhostexe_base + ) + conhost_module = context.module( conhost_symbol_table, proc_layer_name, offset=conhostexe_base ) @@ -560,6 +588,60 @@ class Consoles(interfaces.plugins.PluginInterface): } ) + vollog.debug( + f"Getting ExeAliasList entries for {console_info.ExeAliasList}" + ) + console_properties.append( + { + "level": 1, + "name": "_CONSOLE_INFORMATION.ExeAliasList", + "address": console_info.ExeAliasList.vol.offset, + "data": "", + } + ) + if console_info.ExeAliasList: + for index, exe_alias_list in enumerate( + console_info.get_exe_aliases() + ): + try: + console_properties.append( + { + "level": 2, + "name": f"_CONSOLE_INFORMATION.ExeAliasList.AliasList_{index}", + "address": exe_alias_list.vol.offset, + "data": "", + } + ) + console_properties.append( + { + "level": 2, + "name": f"_CONSOLE_INFORMATION.ExeAliasList.AliasList_{index}.ExeName", + "address": exe_alias_list.ExeName.vol.offset, + "data": exe_alias_list.get_exename(), + } + ) + for alias_index, alias in enumerate(exe_alias_list.get_aliases()): + console_properties.append( + { + "level": 3, + "name": f"_CONSOLE_INFORMATION.ExeAliasList.AliasList_{index}.Alias_{alias_index}.Source", + "address": alias.Source.vol.offset, + "data": alias.get_source(), + } + ) + console_properties.append( + { + "level": 3, + "name": f"_CONSOLE_INFORMATION.ExeAliasList.AliasList_{index}.Alias_{alias_index}.Target", + "address": alias.Target.vol.offset, + "data": alias.get_target(), + } + ) + except Exception as e: + vollog.debug( + f"reading {exe_alias_list} encountered exception {e}" + ) + vollog.debug( f"Getting HistoryList entries for {console_info.HistoryList}" ) @@ -639,60 +721,66 @@ class Consoles(interfaces.plugins.PluginInterface): f"reading {command_history} encountered exception {e}" ) - vollog.debug(f"Getting ScreenBuffer entries for {console_info}") - console_properties.append( - { - "level": 1, - "name": "_CONSOLE_INFORMATION.CurrentScreenBuffer", - "address": console_info.CurrentScreenBuffer.vol.offset, - "data": "", - } - ) - for screen_index, screen_info in enumerate( - console_info.get_screens() - ): - try: - console_properties.append( - { - "level": 2, - "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}", - "address": screen_info, - "data": "", - } - ) - console_properties.append( - { - "level": 2, - "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenX", - "address": None, - "data": screen_info.ScreenX, - } - ) - console_properties.append( - { - "level": 2, - "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenY", - "address": None, - "data": screen_info.ScreenY, - } - ) - console_properties.append( - { - "level": 2, - "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.Dump", - "address": None, - "data": "\n".join(screen_info.get_buffer()), - } - ) - except Exception as e: - vollog.debug( - f"reading {screen_info} encountered exception {e}" - ) + try: + vollog.debug(f"Getting ScreenBuffer entries for {console_info}") + console_properties.append( + { + "level": 1, + "name": "_CONSOLE_INFORMATION.CurrentScreenBuffer", + "address": console_info.CurrentScreenBuffer.vol.offset, + "data": "", + } + ) + for screen_index, screen_info in enumerate( + console_info.get_screens() + ): + try: + console_properties.append( + { + "level": 2, + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}", + "address": screen_info, + "data": "", + } + ) + console_properties.append( + { + "level": 2, + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenX", + "address": None, + "data": screen_info.ScreenX, + } + ) + console_properties.append( + { + "level": 2, + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.ScreenY", + "address": None, + "data": screen_info.ScreenY, + } + ) + console_properties.append( + { + "level": 2, + "name": f"_CONSOLE_INFORMATION.ScreenBuffer_{screen_index}.Dump", + "address": None, + "data": "\n".join(screen_info.get_buffer()), + } + ) + except Exception as e: + vollog.debug( + f"reading {screen_info} encountered exception {e}" + ) + except Exception as e: + vollog.debug( + f"reading _CONSOLE_INFORMATION.CurrentScreenBuffer encountered exception {e}" + ) except exceptions.PagedInvalidAddressException as exp: vollog.debug( f"Required memory at {exp.invalid_address:#x} is not valid" ) + continue yield conhost_proc, console_info, console_properties @@ -776,6 +864,7 @@ class Consoles(interfaces.plugins.PluginInterface): vollog.debug(f"Possible CommandHistorySize values: {max_history}") vollog.debug(f"Possible HistoryBufferMax values: {max_buffers}") + proc = None for proc, console_info, console_properties in self.get_console_info( self.context, kernel.layer_name, @@ -786,13 +875,14 @@ class Consoles(interfaces.plugins.PluginInterface): max_buffers, ): process_name = utility.array_to_string(proc.ImageFileName) + process_pid = proc.UniqueProcessId if console_info and console_properties: for console_property in console_properties: yield ( console_property["level"], ( - proc.UniqueProcessId, + process_pid, process_name, format_hints.Hex(console_info.vol.offset), console_property["name"], @@ -804,6 +894,11 @@ class Consoles(interfaces.plugins.PluginInterface): str(console_property["data"]), ), ) + else: + vollog.warn(f"_CONSOLE_INFORMATION not found for {process_name} with pid {process_pid}.") + + if proc is None: + vollog.warn("No conhost.exe processes found.") def _conhost_proc_filter(self, proc): """ @@ -811,7 +906,7 @@ class Consoles(interfaces.plugins.PluginInterface): """ process_name = utility.array_to_string(proc.ImageFileName) - return process_name != "conhost.exe" + return process_name.lower() != "conhost.exe" def run(self): kernel = self.context.modules[self.config["kernel"]] diff --git a/volatility3/framework/plugins/windows/verinfo.py b/volatility3/framework/plugins/windows/verinfo.py index 57b8dcd3f..4a06ed0c9 100644 --- a/volatility3/framework/plugins/windows/verinfo.py +++ b/volatility3/framework/plugins/windows/verinfo.py @@ -13,7 +13,7 @@ from volatility3.framework.layers import scanners from volatility3.framework.renderers import format_hints from volatility3.framework.symbols import intermed from volatility3.framework.symbols.windows.extensions import pe -from volatility3.plugins.windows import pslist, modules, dlllist +from volatility3.plugins.windows import pslist, modules vollog = logging.getLogger(__name__) diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json index 0a8cb5782..413b6f466 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json @@ -152,8 +152,8 @@ }, "ExeAliasList": { "type": { - "kind": "base", - "name": "unsigned short" + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" }, "offset": 1392 } @@ -562,7 +562,8 @@ } }, "offset": 88 - } }, + } + }, "kind": "struct", "size": 96 }, @@ -581,6 +582,70 @@ }, "kind": "struct", "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "ExeName": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 24 + }, + "AliasList": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 32 + } + }, + "kind": "struct", + "size": 48 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json index 2b98945c9..b3bf9666c 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json @@ -152,8 +152,8 @@ }, "ExeAliasList": { "type": { - "kind": "base", - "name": "unsigned short" + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" }, "offset": 1392 } @@ -562,7 +562,8 @@ } }, "offset": 88 - } }, + } + }, "kind": "struct", "size": 96 }, @@ -581,6 +582,70 @@ }, "kind": "struct", "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 16 + }, + "ExeName": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 24 + }, + "AliasList": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 32 + } + }, + "kind": "struct", + "size": 48 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json index 3d76d1cb4..d962418d3 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json @@ -152,10 +152,10 @@ }, "ExeAliasList": { "type": { - "kind": "base", - "name": "unsigned short" + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" }, - "offset": 1436 + "offset": -856 } }, "kind": "struct", @@ -552,7 +552,8 @@ } }, "offset": 88 - } }, + } + }, "kind": "struct", "size": 96 }, @@ -571,6 +572,70 @@ }, "kind": "struct", "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "ExeName": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 24 + }, + "AliasList": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 32 + } + }, + "kind": "struct", + "size": 48 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json index 681113b0f..0963afee3 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json @@ -1,5 +1,5 @@ { - "symbols": {}, + "symbols": {}, "enums": {}, "base_types": { "unsigned long": { @@ -152,8 +152,8 @@ }, "ExeAliasList": { "type": { - "kind": "base", - "name": "unsigned short" + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" }, "offset": 1436 } @@ -552,7 +552,8 @@ } }, "offset": 88 - } }, + } + }, "kind": "struct", "size": 96 }, @@ -571,6 +572,70 @@ }, "kind": "struct", "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "ExeName": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 24 + }, + "AliasList": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 32 + } + }, + "kind": "struct", + "size": 48 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json index 7bc6ae9d1..cee78e2b5 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json @@ -152,8 +152,11 @@ }, "ExeAliasList": { "type": { - "kind": "base", - "name": "unsigned short" + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } }, "offset": 2410 } @@ -562,7 +565,8 @@ } }, "offset": 88 - } }, + } + }, "kind": "struct", "size": 96 }, @@ -581,6 +585,104 @@ }, "kind": "struct", "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeName": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "AliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 56 + } + }, + "kind": "struct", + "size": 64 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 + }, + "_ALIAS_STRING": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json index f612c527a..59e9fd3b9 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json @@ -152,8 +152,11 @@ }, "ExeAliasList": { "type": { - "kind": "base", - "name": "unsigned short" + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } }, "offset": 9232 } @@ -562,7 +565,8 @@ } }, "offset": 88 - } }, + } + }, "kind": "struct", "size": 96 }, @@ -581,6 +585,104 @@ }, "kind": "struct", "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeName": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "AliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 56 + } + }, + "kind": "struct", + "size": 64 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 + }, + "_ALIAS_STRING": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json index 083a966a0..df02169cb 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json @@ -152,8 +152,11 @@ }, "ExeAliasList": { "type": { - "kind": "base", - "name": "unsigned short" + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } }, "offset": -376 } @@ -562,7 +565,8 @@ } }, "offset": 88 - } }, + } + }, "kind": "struct", "size": 96 }, @@ -581,6 +585,104 @@ }, "kind": "struct", "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeName": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "AliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 56 + } + }, + "kind": "struct", + "size": 64 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 + }, + "_ALIAS_STRING": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json new file mode 100644 index 000000000..0dfaf34af --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json @@ -0,0 +1,722 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 24 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 26 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 136 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 140 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1648 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 1616 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1664 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 1296 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 1272 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 1280 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -920 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -912 + }, + "ExeAliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -1008 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 4 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 6 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 8 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 6 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 32 + }, + "FirstRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 8 + }, + "LastRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 16 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 80 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": -88 + }, + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 0 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": -18 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": -20 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 16 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": -8 + } + }, + "kind": "struct", + "size": 480 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeName": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "AliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 56 + } + }, + "kind": "struct", + "size": 64 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 + }, + "_ALIAS_STRING": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3672-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3672-x64.json new file mode 100644 index 000000000..4c71ee32e --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3672-x64.json @@ -0,0 +1,722 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 2400 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 2402 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2512 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2516 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 2944 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 2912 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 3008 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 2632 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 2608 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2616 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 10640 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 10648 + }, + "ExeAliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 10552 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 4 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 6 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 8 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 6 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 32 + }, + "FirstRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 8 + }, + "LastRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 16 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": -80 + }, + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 0 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": -20 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 16 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": -16 + } + }, + "kind": "struct", + "size": 472 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeName": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "AliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 56 + } + }, + "kind": "struct", + "size": 64 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 + }, + "_ALIAS_STRING": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json new file mode 100644 index 000000000..d6da72ef2 --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json @@ -0,0 +1,722 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 2400 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 2402 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2512 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2516 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 2944 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 2912 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 3008 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 2632 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 2608 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2616 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 10664 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 10672 + }, + "ExeAliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 10576 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 4 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 6 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 8 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 6 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 32 + }, + "FirstRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 8 + }, + "LastRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 16 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 72 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": -96 + }, + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 0 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": -20 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 16 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": -8 + } + }, + "kind": "struct", + "size": 480 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeName": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "AliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 56 + } + }, + "kind": "struct", + "size": 64 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 + }, + "_ALIAS_STRING": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json new file mode 100644 index 000000000..120ad85ec --- /dev/null +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json @@ -0,0 +1,723 @@ +{ + "symbols": {}, + "enums": {}, + "base_types": { + "unsigned long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned char": { + "kind": "char", + "size": 1, + "signed": false, + "endian": "little" + }, + "pointer": { + "kind": "int", + "size": 8, + "signed": false, + "endian": "little" + }, + "unsigned int": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + }, + "unsigned short": { + "kind": "int", + "size": 2, + "signed": false, + "endian": "little" + }, + "short": { + "kind": "int", + "size": 2, + "signed": true, + "endian": "little" + }, + "long": { + "kind": "int", + "size": 4, + "signed": false, + "endian": "little" + } + }, + "user_types": { + "_CONSOLE_INFORMATION": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 2592 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 2594 + }, + "CommandHistorySize": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2704 + }, + "HistoryBufferMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2708 + }, + "OriginalTitle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 3056 + }, + "Title": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 3120 + }, + "GetScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 3216 + }, + "CurrentScreenBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 2824 + }, + "ConsoleProcessList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 2800 + }, + "ProcessCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 2808 + }, + "HistoryList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": -360 + }, + "HistoryBufferCount": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": -352 + }, + "ExeAliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 3776 + } + }, + "kind": "struct", + "size": 140 + }, + "_VECTOR": { + "fields": { + "Begin": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 0 + }, + "End": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_COMMAND" + } + }, + "offset": 8 + }, + "EndCapacity": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "unsigned long" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + }, + "_CONSOLE_PROCESS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ConsoleProcess": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS" + } + }, + "offset": 16 + } + }, + "kind": "struct", + "size": 24 + }, + "_CONSOLE_PROCESS_HANDLE": { + "fields": { + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 52 + }, + "_CONSOLE_PROCESS": { + "fields": { + "ProcessId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 28 + }, + "ThreadId": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 32 + }, + "ProcessHandle": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 24 + }, + "_COMMAND_HISTORY": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "CommandBucket": { + "type": { + "kind": "struct", + "name": "_VECTOR" + }, + "offset": 16 + }, + "CommandCountMax": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 40 + }, + "Application": { + "type": { + "kind": "struct", + "name": "_COMMAND" + }, + "offset": 48 + }, + "ConsoleProcessHandle": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CONSOLE_PROCESS_HANDLE" + } + }, + "offset": 80 + }, + "Flags": { + "type": { + "kind": "base", + "name": "unsigned short" + }, + "offset": 88 + }, + "LastDisplayed": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 92 + } + }, + "kind": "struct", + "size": 96 + }, + "_SCREEN_INFORMATION": { + "fields": { + "TextBufferInfo": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 56 + }, + "Next": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_SCREEN_INFORMATION" + } + }, + "offset": 64 + } + }, + "kind": "struct", + "size": 72 + }, + "_ROW_POINTER": { + "fields": { + "Row": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + + }, + "_ROWS_ARRAY": { + "fields": { + "Rows": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_ROW_POINTER" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_TEXT_BUFFER_INFO": { + "fields": { + "ScreenX": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "ScreenY": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 10 + }, + "BufferRows": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROWS_ARRAY" + } + }, + "offset": 16 + }, + "BufferCapacity": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 10 + }, + "ThisBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": 40 + }, + "FirstRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 16 + }, + "LastRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": 24 + }, + "BufferStart": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 88 + } + }, + "kind": "struct", + "size": 72 + }, + "_CHAR_ROW_CELL": { + "fields": { + "Text": { + "type": { + "kind": "struct", + "name": "nt_symbols!_UNICODE_STRING" + }, + "offset": 0 + }, + "DbcsAttribute": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 2 + } + }, + "kind": "struct", + "size": 3 + }, + "_CHAR_ROW_CELL_ARRAY": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_ROW": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_ROW" + } + }, + "offset": -88 + }, + "CharRow": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_CHAR_ROW_CELL_ARRAY" + } + }, + "offset": 0 + }, + "RowLength": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "Index": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": -20 + }, + "RowLength2": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 8 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "short" + }, + "offset": 16 + }, + "TextBuffer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "_TEXT_BUFFER_INFO" + } + }, + "offset": -8 + } + }, + "kind": "struct", + "size": 464 + }, + "_DEQUE": { + "fields": { + "Blink": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "void" + } + }, + "offset": 0 + } + }, + "kind": "struct", + "size": 8 + }, + "_EXE_ALIAS_LIST": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "ExeName": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "AliasList": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + } + }, + "offset": 56 + } + }, + "kind": "struct", + "size": 64 + }, + "_ALIAS": { + "fields": { + "ListEntry": { + "type": { + "kind": "struct", + "name": "nt_symbols!_LIST_ENTRY" + }, + "offset": 0 + }, + "Source": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 16 + }, + "Target": { + "type": { + "kind": "struct", + "name": "_ALIAS_STRING" + }, + "offset": 48 + } + }, + "kind": "struct", + "size": 32 + }, + "_ALIAS_STRING": { + "fields": { + "Chars": { + "type": { + "count": 1, + "kind": "array", + "subtype": { + "kind": "base", + "name": "unsigned char" + } + }, + "offset": 0 + }, + "Pointer": { + "type": { + "kind": "pointer", + "subtype": { + "kind": "base", + "name": "string" + } + }, + "offset": 0 + }, + "Length": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 16 + }, + "Allocated": { + "type": { + "kind": "base", + "name": "unsigned int" + }, + "offset": 24 + } + }, + "kind": "struct", + "size": 32 + } + }, + "metadata": { + "producer": { + "version": "0.0.1", + "name": "Dave Lassalle", + "datetime": "2024-07-31T15:05:35-06:00" + }, + "format": "4.1.0" + } +} diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 23670bb9b..70ef15093 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -9,30 +9,42 @@ from volatility3.framework import constants class ROW(objects.StructType): """A Row Structure.""" - def _valid_dbcs(self, c): + def _valid_dbcs(self, c, n): # TODO this need more research and testing # https://github.com/search?q=repo%3Amicrosoft%2Fterminal+DbcsAttr&type=code - valid = c in ( + valid = n == 0 and c in ( 0x0, 0x1, 0x2, + 0x8, + 0x10, + 0x18, 0x20, 0x28, 0x30, 0x48, 0x50, + 0x58, 0x60, + 0x68, + 0x70, + 0x78, 0x80, + 0x88, 0xA8, + 0xB8, 0xC0, 0xC8, 0x98, + 0xD8, + 0xE0, + 0xE8, 0xF8, 0xF0, 0xA0, ) - # if not valid: - # print("Bad Dbcs Attribute {}".format(hex(c))) + if n == 0 and not valid: + print("Bad Dbcs Attribute {}".format(hex(c))) return valid def get_text(self, truncate=True): @@ -50,10 +62,9 @@ class ROW(objects.StructType): try: if char_row: line = "".join( - # "{} {} =".format(char_row[i:i + 2].decode('utf-16le', errors='replace'), char_row[i+2]) if self._valid_dbcs(char_row[i+2]) else "" ( char_row[i : i + 2].decode("utf-16le", errors="replace") - if self._valid_dbcs(char_row[i + 2]) + if self._valid_dbcs(char_row[i + 2], char_row[i+1]) else "" ) for i in range(0, len(char_row), 3) @@ -68,12 +79,78 @@ class ROW(objects.StructType): return line +class ALIAS(objects.StructType): + """An Alias Structure""" + + def get_source(self): + if self.Source.Length < 8: + return self.Source.Chars.cast( + "string", + encoding="utf-16", + errors="replace", + max_length=self.Source.Length * 2, + ) + elif self.Source.Length < 1024: + return self.Source.Pointer.dereference().cast( + "string", encoding="utf-16", errors="replace", max_length=512 + ) + + def get_target(self): + if self.Target.Length < 8: + return self.Target.Chars.cast( + "string", + encoding="utf-16", + errors="replace", + max_length=self.Target.Length * 2, + ) + elif self.Target.Length < 1024: + return self.Target.Pointer.dereference().cast( + "string", encoding="utf-16", errors="replace", max_length=512 + ) + +class EXE_ALIAS_LIST(objects.StructType): + """An Exe Alias List Structure""" + + def get_exename(self): + exe_name = self.ExeName + # Windows 10 22000 and Server 20348 removed the Pointer + if isinstance(exe_name, objects.Pointer): + exe_name = exe_name.dereference() + return exe_name.get_string() + + if self.ExeName.Length < 8: + return self.ExeName.Chars.cast( + "string", + encoding="utf-16", + errors="replace", + max_length=self.ExeName.Length * 2, + ) + elif self.ExeName.Length < 1024: + return self.ExeName.Pointer.dereference().cast( + "string", encoding="utf-16", errors="replace", max_length=512 + ) + + def get_aliases(self): + """Generator for the individual aliases for a + particular executable.""" + for alias in self.AliasList.to_list( + f"{self.get_symbol_table_name()}{constants.BANG}_ALIAS", + "ListEntry", + ): + yield alias + + class SCREEN_INFORMATION(objects.StructType): """A Screen Information Structure.""" @property def ScreenX(self): - return self.TextBufferInfo.BufferRows.Rows[0].Row.RowLength2 + # 22000 change from an array of pointers to _ROW to an array of _ROW + row = self.TextBufferInfo.BufferRows.Rows[0] + if hasattr(row, "Row"): + return row.Row.RowLength2 + else: + return row.RowLength2 @property def ScreenY(self): @@ -127,7 +204,9 @@ class SCREEN_INFORMATION(objects.StructType): for i in range(capacity): index = (start + i) % capacity - row = buffer_rows.Rows[index].Row + row = buffer_rows.Rows[index] + if hasattr(row, "Row"): + row = row.Row try: text = row.get_text(truncate_lines) rows.append(text) @@ -138,9 +217,9 @@ class SCREEN_INFORMATION(objects.StructType): rows = self._truncate_rows(rows) if rows: - rows = ["=== Start of buffer ==="] + rows + ["=== End of buffer ==="] + rows = ["=== START OF BUFFER ==="] + rows + ["=== END OF BUFFER ==="] else: - rows = ["=== No buffer data found ==="] + rows = ["=== NO BUFFER DATA FOUND ==="] return rows @@ -198,6 +277,17 @@ class CONSOLE_INFORMATION(objects.StructType): ): yield cmd_hist + def get_exe_aliases(self): + exe_alias_list = self.ExeAliasList + # Windows 10 22000 and Server 20348 made this a Pointer + if isinstance(exe_alias_list, objects.Pointer): + exe_alias_list = exe_alias_list.dereference() + for exe_alias_list_item in exe_alias_list.to_list( + f"{self.get_symbol_table_name()}{constants.BANG}_EXE_ALIAS_LIST", + "ListEntry" + ): + yield exe_alias_list_item + def get_processes(self): for proc in self.ConsoleProcessList.dereference().to_list( f"{self.get_symbol_table_name()}{constants.BANG}_CONSOLE_PROCESS_LIST", @@ -331,6 +421,8 @@ class COMMAND_HISTORY(objects.StructType): win10_x64_class_types = { + "_EXE_ALIAS_LIST": EXE_ALIAS_LIST, + "_ALIAS": ALIAS, "_ROW": ROW, "_SCREEN_INFORMATION": SCREEN_INFORMATION, "_CONSOLE_INFORMATION": CONSOLE_INFORMATION, From 9d98ab9b6548cfc5b36c3e6ade3425ea87498442 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Fri, 27 Sep 2024 10:39:57 -0500 Subject: [PATCH 12/17] #816 - black fixes --- .../framework/plugins/windows/consoles.py | 26 +++++++++++++------ .../symbols/windows/extensions/consoles.py | 5 ++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index 46699aa31..89f9fcc80 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -244,15 +244,19 @@ class Consoles(interfaces.plugins.PluginInterface): configuration.path_join(config_path, "conhost"), "windows", "pe", - class_types=pe.class_types + class_types=pe.class_types, ) try: - (major, minor, product, build) = verinfo.VerInfo.get_version_information( - context, pe_table_name, conhost_layer_name, conhost_base + (major, minor, product, build) = ( + verinfo.VerInfo.get_version_information( + context, pe_table_name, conhost_layer_name, conhost_base + ) ) conhost_mod_version = build - vollog.debug(f"Found conhost.exe version {major}.{minor}.{product}.{build} in {conhost_layer_name} at base {conhost_base:#x}") + vollog.debug( + f"Found conhost.exe version {major}.{minor}.{product}.{build} in {conhost_layer_name} at base {conhost_base:#x}" + ) except (exceptions.InvalidAddressException, TypeError, AttributeError): # the following is IntelLayer specific and might need to be adapted to other architectures. physical_layer_name = context.layers[layer_name].config.get( @@ -432,7 +436,7 @@ class Consoles(interfaces.plugins.PluginInterface): kernel_table_name, config_path, proc_layer_name, - conhostexe_base + conhostexe_base, ) conhost_module = context.module( @@ -620,7 +624,9 @@ class Consoles(interfaces.plugins.PluginInterface): "data": exe_alias_list.get_exename(), } ) - for alias_index, alias in enumerate(exe_alias_list.get_aliases()): + for alias_index, alias in enumerate( + exe_alias_list.get_aliases() + ): console_properties.append( { "level": 3, @@ -722,7 +728,9 @@ class Consoles(interfaces.plugins.PluginInterface): ) try: - vollog.debug(f"Getting ScreenBuffer entries for {console_info}") + vollog.debug( + f"Getting ScreenBuffer entries for {console_info}" + ) console_properties.append( { "level": 1, @@ -895,7 +903,9 @@ class Consoles(interfaces.plugins.PluginInterface): ), ) else: - vollog.warn(f"_CONSOLE_INFORMATION not found for {process_name} with pid {process_pid}.") + vollog.warn( + f"_CONSOLE_INFORMATION not found for {process_name} with pid {process_pid}." + ) if proc is None: vollog.warn("No conhost.exe processes found.") diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 70ef15093..555197fc4 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -64,7 +64,7 @@ class ROW(objects.StructType): line = "".join( ( char_row[i : i + 2].decode("utf-16le", errors="replace") - if self._valid_dbcs(char_row[i + 2], char_row[i+1]) + if self._valid_dbcs(char_row[i + 2], char_row[i + 1]) else "" ) for i in range(0, len(char_row), 3) @@ -108,6 +108,7 @@ class ALIAS(objects.StructType): "string", encoding="utf-16", errors="replace", max_length=512 ) + class EXE_ALIAS_LIST(objects.StructType): """An Exe Alias List Structure""" @@ -284,7 +285,7 @@ class CONSOLE_INFORMATION(objects.StructType): exe_alias_list = exe_alias_list.dereference() for exe_alias_list_item in exe_alias_list.to_list( f"{self.get_symbol_table_name()}{constants.BANG}_EXE_ALIAS_LIST", - "ListEntry" + "ListEntry", ): yield exe_alias_list_item From bd678eaf80482d4285e3409288a7dfd116dccd82 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Fri, 27 Sep 2024 16:07:44 -0500 Subject: [PATCH 13/17] #816 - fix cmdscan --- .../framework/plugins/windows/cmdscan.py | 78 ++++++++++++------- .../framework/plugins/windows/consoles.py | 38 +++++---- 2 files changed, 75 insertions(+), 41 deletions(-) diff --git a/volatility3/framework/plugins/windows/cmdscan.py b/volatility3/framework/plugins/windows/cmdscan.py index b92d7efab..09cb0f316 100644 --- a/volatility3/framework/plugins/windows/cmdscan.py +++ b/volatility3/framework/plugins/windows/cmdscan.py @@ -14,17 +14,9 @@ from volatility3.framework.configuration import requirements from volatility3.framework.layers import scanners from volatility3.framework.objects import utility from volatility3.framework.renderers import format_hints -from volatility3.plugins.windows import pslist, vadinfo, info, verinfo, consoles -from volatility3.plugins.windows.registry import hivelist +from volatility3.plugins.windows import pslist, consoles -try: - import capstone - - has_capstone = True -except ImportError: - has_capstone = False - vollog = logging.getLogger(__name__) @@ -32,6 +24,7 @@ class CmdScan(interfaces.plugins.PluginInterface): """Looks for Windows Command History lists""" _required_framework_version = (2, 4, 0) + _version = (1, 0, 0) @classmethod def get_requirements(cls): @@ -46,7 +39,7 @@ class CmdScan(interfaces.plugins.PluginInterface): name="pslist", component=pslist.PsList, version=(2, 0, 0) ), requirements.PluginRequirement( - name="hivelist", plugin=hivelist.HiveList, version=(1, 0, 0) + name="consoles", plugin=consoles.Consoles, version=(1, 0, 0) ), requirements.BooleanRequirement( name="no_registry", @@ -70,7 +63,7 @@ class CmdScan(interfaces.plugins.PluginInterface): size_filter: Optional[int] = 0x40000000, ) -> List[Tuple[int, int]]: """ - Returns vads of a process with smaller than size_filter + Returns vads of a process with size smaller than size_filter Args: conhost_proc: the process object for conhost.exe @@ -114,12 +107,10 @@ class CmdScan(interfaces.plugins.PluginInterface): Returns: The conhost process object, the command history structure, a dictionary of properties for - that command historyn structure. + that command history structure. """ - conhost_symbol_table = consoles.Consoles.create_conhost_symbol_table( - context, kernel_layer_name, kernel_table_name, config_path - ) + conhost_symbol_table = None for conhost_proc, proc_layer_name in consoles.Consoles.find_conhost_proc(procs): if not conhost_proc: @@ -143,11 +134,22 @@ class CmdScan(interfaces.plugins.PluginInterface): proc_layer = context.layers[proc_layer_name] + if conhost_symbol_table is None: + conhost_symbol_table = consoles.Consoles.create_conhost_symbol_table( + context, + kernel_layer_name, + kernel_table_name, + config_path, + proc_layer_name, + conhostexe_base, + ) + conhost_module = context.module( conhost_symbol_table, proc_layer_name, offset=conhostexe_base ) sections = cls.get_filtered_vads(conhost_proc) + found_history_for_proc = False # scan for potential _COMMAND_HISTORY structures by using the CommandHistorySize for max_history_value in max_history: max_history_bytes = struct.pack("H", max_history_value) @@ -258,7 +260,12 @@ class CmdScan(interfaces.plugins.PluginInterface): f"reading {command_history} encountered exception {e}" ) - yield conhost_proc, command_history, command_history_properties + if command_history and command_history_properties: + found_history_for_proc = True + yield conhost_proc, command_history, command_history_properties + + if not found_history_for_proc: + yield conhost_proc, command_history or None, [] def _generator( self, procs: Generator[interfaces.objects.ObjectInterface, None, None] @@ -276,19 +283,18 @@ class CmdScan(interfaces.plugins.PluginInterface): no_registry = self.config.get("no_registry") if no_registry is False: - max_history, _max_buffers = ( - consoles.Consoles.get_console_settings_from_registry( - self.context, - self.config_path, - kernel.layer_name, - kernel.symbol_table_name, - max_history, - [], - ) + max_history, _ = consoles.Consoles.get_console_settings_from_registry( + self.context, + self.config_path, + kernel.layer_name, + kernel.symbol_table_name, + max_history, + [], ) vollog.debug(f"Possible CommandHistorySize values: {max_history}") + proc = None for ( proc, command_history, @@ -302,13 +308,14 @@ class CmdScan(interfaces.plugins.PluginInterface): max_history, ): process_name = utility.array_to_string(proc.ImageFileName) + process_pid = proc.UniqueProcessId if command_history and command_history_properties: for command_history_property in command_history_properties: yield ( command_history_property["level"], ( - proc.UniqueProcessId, + process_pid, process_name, format_hints.Hex(command_history.vol.offset), command_history_property["name"], @@ -322,6 +329,25 @@ class CmdScan(interfaces.plugins.PluginInterface): str(command_history_property["data"]), ), ) + else: + yield ( + 0, + ( + process_pid, + process_name, + ( + format_hints.Hex(command_history.vol.offset) + if command_history + else renderers.NotApplicableValue() + ), + "_COMMAND_HISTORY", + renderers.NotApplicableValue(), + "History Not Found", + ), + ) + + if proc is None: + vollog.warn("No conhost.exe processes found.") def _conhost_proc_filter(self, proc): """ diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index 89f9fcc80..a2eade321 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -17,19 +17,11 @@ from volatility3.framework.layers import scanners from volatility3.framework.objects import utility from volatility3.framework.renderers import format_hints from volatility3.framework.symbols import intermed -from volatility3.framework.symbols.windows import pdbutil from volatility3.framework.symbols.windows.extensions import pe, consoles -from volatility3.plugins.windows import pslist, vadinfo, info, verinfo +from volatility3.plugins.windows import pslist, info, verinfo from volatility3.plugins.windows.registry import hivelist -try: - import capstone - - has_capstone = True -except ImportError: - has_capstone = False - vollog = logging.getLogger(__name__) @@ -37,6 +29,7 @@ class Consoles(interfaces.plugins.PluginInterface): """Looks for Windows console buffers""" _required_framework_version = (2, 4, 0) + _version = (1, 0, 0) @classmethod def get_requirements(cls): @@ -53,9 +46,6 @@ class Consoles(interfaces.plugins.PluginInterface): requirements.VersionRequirement( name="verinfo", component=verinfo.VerInfo, version=(1, 0, 0) ), - requirements.VersionRequirement( - name="pdbutil", component=pdbutil.PDBUtility, version=(1, 0, 0) - ), requirements.PluginRequirement( name="hivelist", plugin=hivelist.HiveList, version=(1, 0, 0) ), @@ -443,6 +433,7 @@ class Consoles(interfaces.plugins.PluginInterface): conhost_symbol_table, proc_layer_name, offset=conhostexe_base ) + found_console_info_for_proc = False # scan for potential _CONSOLE_INFORMATION structures by using the CommandHistorySize for max_history_value in max_history: max_history_bytes = struct.pack("H", max_history_value) @@ -790,7 +781,12 @@ class Consoles(interfaces.plugins.PluginInterface): ) continue - yield conhost_proc, console_info, console_properties + if console_info and console_properties: + found_console_info_for_proc = True + yield conhost_proc, console_info, console_properties + + if not found_console_info_for_proc: + yield conhost_proc, console_info or None, [] @classmethod def get_console_settings_from_registry( @@ -903,8 +899,20 @@ class Consoles(interfaces.plugins.PluginInterface): ), ) else: - vollog.warn( - f"_CONSOLE_INFORMATION not found for {process_name} with pid {process_pid}." + yield ( + 0, + ( + process_pid, + process_name, + ( + format_hints.Hex(console_info.vol.offset) + if console_info + else renderers.NotApplicableValue() + ), + "_CONSOLE_INFORMATION", + renderers.NotApplicableValue(), + "Console Information Not Found", + ), ) if proc is None: From ece2dbe9a77947d31eaaf7da7cbb1a6cea5f330d Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Tue, 1 Oct 2024 13:00:15 -0500 Subject: [PATCH 14/17] #816 formatting fixes --- .../framework/plugins/windows/consoles.py | 4 ++-- .../symbols/windows/extensions/consoles.py | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index a2eade321..dfc14f2d6 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -168,7 +168,7 @@ class Consoles(interfaces.plugins.PluginInterface): raise NotImplementedError( "Kernel Debug Structure version format not supported!" ) - except: + except Exception: # unsure what to raise here. Also, it might be useful to add some kind of fallback, # either to a user-provided version or to another method to determine conhost.exe's version raise exceptions.VolatilityException( @@ -834,7 +834,7 @@ class Consoles(interfaces.plugins.PluginInterface): max_history.add(value.decode_data()) elif val_name == "NumberOfHistoryBuffers": max_buffers.add(value.decode_data()) - except: + except Exception: continue return max_history, max_buffers diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 555197fc4..390b6858d 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -95,6 +95,8 @@ class ALIAS(objects.StructType): "string", encoding="utf-16", errors="replace", max_length=512 ) + return None + def get_target(self): if self.Target.Length < 8: return self.Target.Chars.cast( @@ -108,6 +110,8 @@ class ALIAS(objects.StructType): "string", encoding="utf-16", errors="replace", max_length=512 ) + return None + class EXE_ALIAS_LIST(objects.StructType): """An Exe Alias List Structure""" @@ -131,6 +135,8 @@ class EXE_ALIAS_LIST(objects.StructType): "string", encoding="utf-16", errors="replace", max_length=512 ) + return None + def get_aliases(self): """Generator for the individual aliases for a particular executable.""" @@ -211,7 +217,7 @@ class SCREEN_INFORMATION(objects.StructType): try: text = row.get_text(truncate_lines) rows.append(text) - except: + except Exception: break if truncate_rows: @@ -301,7 +307,7 @@ class CONSOLE_INFORMATION(objects.StructType): return self.Title.dereference().cast( "string", encoding="utf-16", errors="replace", max_length=512 ) - except: + except Exception: return "" def get_original_title(self): @@ -309,7 +315,7 @@ class CONSOLE_INFORMATION(objects.StructType): return self.OriginalTitle.dereference().cast( "string", encoding="utf-16", errors="replace", max_length=512 ) - except: + except Exception: return "" @@ -340,6 +346,8 @@ class COMMAND(objects.StructType): "string", encoding="utf-16", errors="replace", max_length=512 ) + return None + class COMMAND_HISTORY(objects.StructType): """A Command History Structure.""" @@ -387,6 +395,8 @@ class COMMAND_HISTORY(objects.StructType): "string", encoding="utf-16", errors="replace", max_length=512 ) + return None + def scan_command_bucket(self, end=None): """Brute force print all strings pointed to by the CommandBucket entries by going to greater of EndCapacity or CommandCountMax*sizeof(_COMMAND)""" From 0dd082b7fda2d762026a823b38ba004819b039be Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Mon, 7 Oct 2024 12:26:17 -0500 Subject: [PATCH 15/17] #816 initial PR comment fixes --- .../framework/plugins/windows/cmdscan.py | 43 +++--- .../framework/plugins/windows/consoles.py | 6 +- .../consoles-win10-17763-3232-x64.json | 4 +- .../consoles/consoles-win10-17763-x64.json | 4 +- .../consoles/consoles-win10-18362-x64.json | 4 +- .../consoles/consoles-win10-19041-x64.json | 4 +- .../consoles-win10-20348-1970-x64.json | 47 +----- .../consoles-win10-20348-2461-x64.json | 47 +----- .../consoles/consoles-win10-20348-x64.json | 47 +----- .../consoles/consoles-win10-22000-x64.json | 47 +----- ...son => consoles-win10-22621-3527-x64.json} | 47 +----- .../consoles/consoles-win10-22621-x64.json | 47 +----- .../consoles/consoles-win10-25398-x64.json | 47 +----- .../symbols/windows/extensions/consoles.py | 144 +++++++----------- 14 files changed, 111 insertions(+), 427 deletions(-) rename volatility3/framework/symbols/windows/consoles/{consoles-win10-22621-3672-x64.json => consoles-win10-22621-3527-x64.json} (93%) diff --git a/volatility3/framework/plugins/windows/cmdscan.py b/volatility3/framework/plugins/windows/cmdscan.py index 09cb0f316..9a3460a20 100644 --- a/volatility3/framework/plugins/windows/cmdscan.py +++ b/volatility3/framework/plugins/windows/cmdscan.py @@ -61,7 +61,7 @@ class CmdScan(interfaces.plugins.PluginInterface): cls, conhost_proc: interfaces.context.ContextInterface, size_filter: Optional[int] = 0x40000000, - ) -> List[Tuple[int, int]]: + ) -> Generator[Tuple[int, int], None, None]: """ Returns vads of a process with size smaller than size_filter @@ -73,20 +73,17 @@ class CmdScan(interfaces.plugins.PluginInterface): vad_base: the base address vad_size: the size of the VAD """ - vads = [] for vad in conhost_proc.get_vad_root().traverse(): base = vad.get_start() if vad.get_size() < size_filter: - vads.append((base, vad.get_size())) - - return vads + yield (base, vad.get_size()) @classmethod def get_command_history( cls, context: interfaces.context.ContextInterface, kernel_layer_name: str, - kernel_table_name: str, + kernel_symbol_table_name: str, config_path: str, procs: Generator[interfaces.objects.ObjectInterface, None, None], max_history: Set[int], @@ -100,7 +97,7 @@ class CmdScan(interfaces.plugins.PluginInterface): Args: context: The context to retrieve required elements (layers, symbol tables) from kernel_layer_name: The name of the layer on which to operate - kernel_table_name: The name of the table containing the kernel symbols + kernel_symbol_table_name: The name of the table containing the kernel symbols config_path: The config path where to find symbol files procs: list of process objects max_history: an initial set of CommandHistorySize values @@ -138,7 +135,7 @@ class CmdScan(interfaces.plugins.PluginInterface): conhost_symbol_table = consoles.Consoles.create_conhost_symbol_table( context, kernel_layer_name, - kernel_table_name, + kernel_symbol_table_name, config_path, proc_layer_name, conhostexe_base, @@ -147,6 +144,9 @@ class CmdScan(interfaces.plugins.PluginInterface): conhost_module = context.module( conhost_symbol_table, proc_layer_name, offset=conhostexe_base ) + command_count_max_offset = conhost_module.get_type( + "_COMMAND_HISTORY" + ).relative_child_offset("CommandCountMax") sections = cls.get_filtered_vads(conhost_proc) found_history_for_proc = False @@ -161,15 +161,13 @@ class CmdScan(interfaces.plugins.PluginInterface): scanners.BytesScanner(max_history_bytes), sections=sections, ): + command_history = None command_history_properties = [] try: command_history = conhost_module.object( "_COMMAND_HISTORY", - offset=address - - conhost_module.get_type( - "_COMMAND_HISTORY" - ).relative_child_offset("CommandCountMax"), + offset=address - command_count_max_offset, absolute=True, ) @@ -184,13 +182,13 @@ class CmdScan(interfaces.plugins.PluginInterface): "level": 0, "name": "_COMMAND_HISTORY", "address": command_history.vol.offset, - "data": "", + "data": None, } ) command_history_properties.append( { "level": 1, - "name": f"_COMMAND_HISTORY.Application", + "name": "_COMMAND_HISTORY.Application", "address": command_history.Application.vol.offset, "data": command_history.get_application(), } @@ -198,7 +196,7 @@ class CmdScan(interfaces.plugins.PluginInterface): command_history_properties.append( { "level": 1, - "name": f"_COMMAND_HISTORY.ProcessHandle", + "name": "_COMMAND_HISTORY.ProcessHandle", "address": command_history.ConsoleProcessHandle.ProcessHandle.vol.offset, "data": hex( command_history.ConsoleProcessHandle.ProcessHandle @@ -208,7 +206,7 @@ class CmdScan(interfaces.plugins.PluginInterface): command_history_properties.append( { "level": 1, - "name": f"_COMMAND_HISTORY.CommandCount", + "name": "_COMMAND_HISTORY.CommandCount", "address": None, "data": command_history.CommandCount, } @@ -216,7 +214,7 @@ class CmdScan(interfaces.plugins.PluginInterface): command_history_properties.append( { "level": 1, - "name": f"_COMMAND_HISTORY.LastDisplayed", + "name": "_COMMAND_HISTORY.LastDisplayed", "address": command_history.LastDisplayed.vol.offset, "data": command_history.LastDisplayed, } @@ -224,7 +222,7 @@ class CmdScan(interfaces.plugins.PluginInterface): command_history_properties.append( { "level": 1, - "name": f"_COMMAND_HISTORY.CommandCountMax", + "name": "_COMMAND_HISTORY.CommandCountMax", "address": command_history.CommandCountMax.vol.offset, "data": command_history.CommandCountMax, } @@ -233,7 +231,7 @@ class CmdScan(interfaces.plugins.PluginInterface): command_history_properties.append( { "level": 1, - "name": f"_COMMAND_HISTORY.CommandBucket", + "name": "_COMMAND_HISTORY.CommandBucket", "address": command_history.CommandBucket.vol.offset, "data": "", } @@ -248,7 +246,7 @@ class CmdScan(interfaces.plugins.PluginInterface): "level": 2, "name": f"_COMMAND_HISTORY.CommandBucket_Command_{cmd_index}", "address": bucket_cmd.vol.offset, - "data": bucket_cmd.get_command(), + "data": bucket_cmd.get_command_string(), } ) except Exception as e: @@ -264,6 +262,9 @@ class CmdScan(interfaces.plugins.PluginInterface): found_history_for_proc = True yield conhost_proc, command_history, command_history_properties + # if found_history_for_proc is still False, then none of the scanned locations found + # a valid _COMMAND_HISTORY for the process, so yield the process and some empty data + # so the process can at least be reported that it was found with no history if not found_history_for_proc: yield conhost_proc, command_history or None, [] @@ -349,7 +350,7 @@ class CmdScan(interfaces.plugins.PluginInterface): if proc is None: vollog.warn("No conhost.exe processes found.") - def _conhost_proc_filter(self, proc): + def _conhost_proc_filter(self, proc: interfaces.objects.ObjectInterface): """ Used to filter to only conhost.exe processes """ diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index dfc14f2d6..cef7cba46 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -209,7 +209,7 @@ class Consoles(interfaces.plugins.PluginInterface): (10, 0, 20348, 2520): "consoles-win10-20348-2461-x64", (10, 0, 22000, 0): "consoles-win10-22000-x64", (10, 0, 22621, 1): "consoles-win10-22621-x64", - (10, 0, 22621, 3672): "consoles-win10-22621-3672-x64", + (10, 0, 22621, 3527): "consoles-win10-22621-3527-x64", (10, 0, 25398, 0): "consoles-win10-22000-x64", } @@ -706,7 +706,7 @@ class Consoles(interfaces.plugins.PluginInterface): "level": 3, "name": f"_CONSOLE_INFORMATION.HistoryList.CommandHistory_{index}_Command_{cmd_index}", "address": bucket_cmd.vol.offset, - "data": bucket_cmd.get_command(), + "data": bucket_cmd.get_command_string(), } ) except Exception as e: @@ -918,7 +918,7 @@ class Consoles(interfaces.plugins.PluginInterface): if proc is None: vollog.warn("No conhost.exe processes found.") - def _conhost_proc_filter(self, proc): + def _conhost_proc_filter(self, proc: interfaces.objects.ObjectInterface) -> bool: """ Used to filter to only conhost.exe processes """ diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json index 413b6f466..13382c7ee 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-3232-x64.json @@ -632,14 +632,14 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json index b3bf9666c..f813691bc 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-17763-x64.json @@ -632,14 +632,14 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json index d962418d3..85ef9d718 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-18362-x64.json @@ -622,14 +622,14 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json index 0963afee3..8f6dd8c6a 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-19041-x64.json @@ -622,14 +622,14 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json index cee78e2b5..8357ece4a 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-1970-x64.json @@ -598,7 +598,7 @@ "ExeName": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, @@ -628,61 +628,20 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } }, "kind": "struct", "size": 32 - }, - "_ALIAS_STRING": { - "fields": { - "Chars": { - "type": { - "count": 1, - "kind": "array", - "subtype": { - "kind": "base", - "name": "unsigned char" - } - }, - "offset": 0 - }, - "Pointer": { - "type": { - "kind": "pointer", - "subtype": { - "kind": "base", - "name": "string" - } - }, - "offset": 0 - }, - "Length": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 16 - }, - "Allocated": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 24 - } - }, - "kind": "struct", - "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json index 59e9fd3b9..f80a99148 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-2461-x64.json @@ -598,7 +598,7 @@ "ExeName": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, @@ -628,61 +628,20 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } }, "kind": "struct", "size": 32 - }, - "_ALIAS_STRING": { - "fields": { - "Chars": { - "type": { - "count": 1, - "kind": "array", - "subtype": { - "kind": "base", - "name": "unsigned char" - } - }, - "offset": 0 - }, - "Pointer": { - "type": { - "kind": "pointer", - "subtype": { - "kind": "base", - "name": "string" - } - }, - "offset": 0 - }, - "Length": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 16 - }, - "Allocated": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 24 - } - }, - "kind": "struct", - "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json index df02169cb..5c7fc8473 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-20348-x64.json @@ -598,7 +598,7 @@ "ExeName": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, @@ -628,61 +628,20 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } }, "kind": "struct", "size": 32 - }, - "_ALIAS_STRING": { - "fields": { - "Chars": { - "type": { - "count": 1, - "kind": "array", - "subtype": { - "kind": "base", - "name": "unsigned char" - } - }, - "offset": 0 - }, - "Pointer": { - "type": { - "kind": "pointer", - "subtype": { - "kind": "base", - "name": "string" - } - }, - "offset": 0 - }, - "Length": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 16 - }, - "Allocated": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 24 - } - }, - "kind": "struct", - "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json index 0dfaf34af..cf38d3e14 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-22000-x64.json @@ -624,7 +624,7 @@ "ExeName": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, @@ -654,61 +654,20 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } }, "kind": "struct", "size": 32 - }, - "_ALIAS_STRING": { - "fields": { - "Chars": { - "type": { - "count": 1, - "kind": "array", - "subtype": { - "kind": "base", - "name": "unsigned char" - } - }, - "offset": 0 - }, - "Pointer": { - "type": { - "kind": "pointer", - "subtype": { - "kind": "base", - "name": "string" - } - }, - "offset": 0 - }, - "Length": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 16 - }, - "Allocated": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 24 - } - }, - "kind": "struct", - "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3672-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3527-x64.json similarity index 93% rename from volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3672-x64.json rename to volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3527-x64.json index 4c71ee32e..a5bda0f35 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3672-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-3527-x64.json @@ -624,7 +624,7 @@ "ExeName": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, @@ -654,61 +654,20 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } }, "kind": "struct", "size": 32 - }, - "_ALIAS_STRING": { - "fields": { - "Chars": { - "type": { - "count": 1, - "kind": "array", - "subtype": { - "kind": "base", - "name": "unsigned char" - } - }, - "offset": 0 - }, - "Pointer": { - "type": { - "kind": "pointer", - "subtype": { - "kind": "base", - "name": "string" - } - }, - "offset": 0 - }, - "Length": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 16 - }, - "Allocated": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 24 - } - }, - "kind": "struct", - "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json index d6da72ef2..44f926a87 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-22621-x64.json @@ -624,7 +624,7 @@ "ExeName": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, @@ -654,61 +654,20 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } }, "kind": "struct", "size": 32 - }, - "_ALIAS_STRING": { - "fields": { - "Chars": { - "type": { - "count": 1, - "kind": "array", - "subtype": { - "kind": "base", - "name": "unsigned char" - } - }, - "offset": 0 - }, - "Pointer": { - "type": { - "kind": "pointer", - "subtype": { - "kind": "base", - "name": "string" - } - }, - "offset": 0 - }, - "Length": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 16 - }, - "Allocated": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 24 - } - }, - "kind": "struct", - "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json b/volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json index 120ad85ec..5e91d8824 100644 --- a/volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json +++ b/volatility3/framework/symbols/windows/consoles/consoles-win10-25398-x64.json @@ -625,7 +625,7 @@ "ExeName": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, @@ -655,61 +655,20 @@ "Source": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 16 }, "Target": { "type": { "kind": "struct", - "name": "_ALIAS_STRING" + "name": "_COMMAND" }, "offset": 48 } }, "kind": "struct", "size": 32 - }, - "_ALIAS_STRING": { - "fields": { - "Chars": { - "type": { - "count": 1, - "kind": "array", - "subtype": { - "kind": "base", - "name": "unsigned char" - } - }, - "offset": 0 - }, - "Pointer": { - "type": { - "kind": "pointer", - "subtype": { - "kind": "base", - "name": "string" - } - }, - "offset": 0 - }, - "Length": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 16 - }, - "Allocated": { - "type": { - "kind": "base", - "name": "unsigned int" - }, - "offset": 24 - } - }, - "kind": "struct", - "size": 32 } }, "metadata": { diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 390b6858d..96f7892a5 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -2,17 +2,21 @@ # which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 # -from volatility3.framework import objects +import logging +from typing import Generator, List, Union, Tuple +from volatility3.framework import objects, interfaces from volatility3.framework import constants +vollog = logging.getLogger(__name__) + class ROW(objects.StructType): """A Row Structure.""" - def _valid_dbcs(self, c, n): + def _valid_dbcs(self, dbcs_attr: int, text_attr_msb: int) -> bool: # TODO this need more research and testing # https://github.com/search?q=repo%3Amicrosoft%2Fterminal+DbcsAttr&type=code - valid = n == 0 and c in ( + valid = text_attr_msb == 0 and dbcs_attr in ( 0x0, 0x1, 0x2, @@ -43,11 +47,11 @@ class ROW(objects.StructType): 0xF0, 0xA0, ) - if n == 0 and not valid: - print("Bad Dbcs Attribute {}".format(hex(c))) + if text_attr_msb == 0 and not valid: + vollog.debug(f"Bad Dbcs Attribute {dbcs_attr:#x}") return valid - def get_text(self, truncate=True): + def get_text(self, truncate: bool = True) -> str: """A convenience method to extract the text from the _ROW. The _ROW contains a pointer CharRow to an array of CharRowCell objects. Each CharRowCell contains the wide character and an attribute. Enumerating @@ -70,7 +74,6 @@ class ROW(objects.StructType): for i in range(0, len(char_row), 3) ) except Exception as e: - print(e) line = "" if truncate: @@ -82,62 +85,26 @@ class ROW(objects.StructType): class ALIAS(objects.StructType): """An Alias Structure""" - def get_source(self): - if self.Source.Length < 8: - return self.Source.Chars.cast( - "string", - encoding="utf-16", - errors="replace", - max_length=self.Source.Length * 2, - ) - elif self.Source.Length < 1024: - return self.Source.Pointer.dereference().cast( - "string", encoding="utf-16", errors="replace", max_length=512 - ) + def get_source(self) -> Union[str, None]: + return self.Source.get_command_string() - return None - - def get_target(self): - if self.Target.Length < 8: - return self.Target.Chars.cast( - "string", - encoding="utf-16", - errors="replace", - max_length=self.Target.Length * 2, - ) - elif self.Target.Length < 1024: - return self.Target.Pointer.dereference().cast( - "string", encoding="utf-16", errors="replace", max_length=512 - ) - - return None + def get_target(self) -> Union[str, None]: + return self.Target.get_command_string() class EXE_ALIAS_LIST(objects.StructType): """An Exe Alias List Structure""" - def get_exename(self): + def get_exename(self) -> Union[str, None]: exe_name = self.ExeName # Windows 10 22000 and Server 20348 removed the Pointer if isinstance(exe_name, objects.Pointer): exe_name = exe_name.dereference() return exe_name.get_string() - if self.ExeName.Length < 8: - return self.ExeName.Chars.cast( - "string", - encoding="utf-16", - errors="replace", - max_length=self.ExeName.Length * 2, - ) - elif self.ExeName.Length < 1024: - return self.ExeName.Pointer.dereference().cast( - "string", encoding="utf-16", errors="replace", max_length=512 - ) + return exe_name.get_command_string() - return None - - def get_aliases(self): + def get_aliases(self) -> Generator[interfaces.objects.ObjectInterface, None, None]: """Generator for the individual aliases for a particular executable.""" for alias in self.AliasList.to_list( @@ -151,7 +118,7 @@ class SCREEN_INFORMATION(objects.StructType): """A Screen Information Structure.""" @property - def ScreenX(self): + def ScreenX(self) -> int: # 22000 change from an array of pointers to _ROW to an array of _ROW row = self.TextBufferInfo.BufferRows.Rows[0] if hasattr(row, "Row"): @@ -160,10 +127,10 @@ class SCREEN_INFORMATION(objects.StructType): return row.RowLength2 @property - def ScreenY(self): + def ScreenY(self) -> int: return self.TextBufferInfo.BufferCapacity - def _truncate_rows(self, rows): + def _truncate_rows(self, rows: List[str]) -> List[str]: """To truncate empty rows at the end, walk the list backwards and get the last non-empty row. Use that row index to splice. Rows are created based on the @@ -187,7 +154,9 @@ class SCREEN_INFORMATION(objects.StructType): return rows - def get_buffer(self, truncate_rows=True, truncate_lines=True): + def get_buffer( + self, truncate_rows: bool = True, truncate_lines: bool = True + ) -> List[str]: """Get the screen buffer. The screen buffer is comprised of the screen's Y @@ -206,7 +175,7 @@ class SCREEN_INFORMATION(objects.StructType): capacity = self.TextBufferInfo.BufferCapacity start = self.TextBufferInfo.BufferStart - buffer_rows = self.TextBufferInfo.BufferRows.dereference() + buffer_rows = self.TextBufferInfo.BufferRows buffer_rows.Rows.count = self.TextBufferInfo.BufferCapacity for i in range(capacity): @@ -234,10 +203,10 @@ class CONSOLE_INFORMATION(objects.StructType): """A Console Information Structure.""" @property - def ScreenBuffer(self): + def ScreenBuffer(self) -> interfaces.objects.ObjectInterface: return self.GetScreenBuffer - def is_valid(self, max_buffers=4) -> bool: + def is_valid(self, max_buffers: int = 4) -> bool: """Determine if the structure is valid.""" # Last displayed must be between -1 and max @@ -249,7 +218,7 @@ class CONSOLE_INFORMATION(objects.StructType): return True - def get_screens(self): + def get_screens(self) -> Generator[interfaces.objects.ObjectInterface, None, None]: """Generator for screens in the console. A console can have multiple screen buffers at a time, @@ -277,14 +246,18 @@ class CONSOLE_INFORMATION(objects.StructType): seen.add(cur.vol.offset) cur = cur.Next - def get_histories(self): - for cmd_hist in self.HistoryList.dereference().to_list( + def get_histories( + self, + ) -> Generator[interfaces.objects.ObjectInterface, None, None]: + for cmd_hist in self.HistoryList.to_list( f"{self.get_symbol_table_name()}{constants.BANG}_COMMAND_HISTORY", "ListEntry", ): yield cmd_hist - def get_exe_aliases(self): + def get_exe_aliases( + self, + ) -> Generator[interfaces.objects.ObjectInterface, None, None]: exe_alias_list = self.ExeAliasList # Windows 10 22000 and Server 20348 made this a Pointer if isinstance(exe_alias_list, objects.Pointer): @@ -295,14 +268,16 @@ class CONSOLE_INFORMATION(objects.StructType): ): yield exe_alias_list_item - def get_processes(self): - for proc in self.ConsoleProcessList.dereference().to_list( + def get_processes( + self, + ) -> Generator[interfaces.objects.ObjectInterface, None, None]: + for proc in self.ConsoleProcessList.to_list( f"{self.get_symbol_table_name()}{constants.BANG}_CONSOLE_PROCESS_LIST", "ListEntry", ): yield proc - def get_title(self): + def get_title(self) -> Union[str, None]: try: return self.Title.dereference().cast( "string", encoding="utf-16", errors="replace", max_length=512 @@ -310,7 +285,7 @@ class CONSOLE_INFORMATION(objects.StructType): except Exception: return "" - def get_original_title(self): + def get_original_title(self) -> Union[str, None]: try: return self.OriginalTitle.dereference().cast( "string", encoding="utf-16", errors="replace", max_length=512 @@ -322,7 +297,7 @@ class CONSOLE_INFORMATION(objects.StructType): class COMMAND(objects.StructType): """A Command Structure""" - def is_valid(self): + def is_valid(self) -> bool: if ( self.Length < 1 or self.Allocated < 1 @@ -333,7 +308,7 @@ class COMMAND(objects.StructType): return True - def get_command(self): + def get_command_string(self) -> Union[str, None]: if self.Length < 8: return self.Chars.cast( "string", @@ -343,7 +318,10 @@ class COMMAND(objects.StructType): ) elif self.Length < 1024: return self.Pointer.dereference().cast( - "string", encoding="utf-16", errors="replace", max_length=512 + "string", + encoding="utf-16", + errors="replace", + max_length=self.Length * 2, ) return None @@ -353,17 +331,17 @@ class COMMAND_HISTORY(objects.StructType): """A Command History Structure.""" @property - def CommandCount(self): + def CommandCount(self) -> int: command_type = self.get_symbol_table_name() + constants.BANG + "_COMMAND" command_size = self._context.symbol_space.get_type(command_type).size return int((self.CommandBucket.End - self.CommandBucket.Begin) / command_size) @property - def ProcessHandle(self): + def ProcessHandle(self) -> int: """Allow ProcessHandle to be referenced regardless of OS version""" return self.ConsoleProcessHandle.ProcessHandle - def is_valid(self, max_history=50): + def is_valid(self, max_history: int = 50) -> bool: # The count must be between zero and max if self.CommandCount < 0 or self.CommandCount > max_history: return False @@ -382,22 +360,12 @@ class COMMAND_HISTORY(objects.StructType): return True - def get_application(self): - if self.Application.Length < 8: - return self.Application.Chars.cast( - "string", - encoding="utf-16", - errors="replace", - max_length=self.Application.Length * 2, - ) - elif self.Application.Length < 1024: - return self.Application.Pointer.dereference().cast( - "string", encoding="utf-16", errors="replace", max_length=512 - ) + def get_application(self) -> Union[str, None]: + return self.Application.get_command_string() - return None - - def scan_command_bucket(self, end=None): + def scan_command_bucket( + self, end: Union[int, None] = None + ) -> Generator[Tuple[int, interfaces.objects.ObjectInterface], None, None]: """Brute force print all strings pointed to by the CommandBucket entries by going to greater of EndCapacity or CommandCountMax*sizeof(_COMMAND)""" @@ -418,7 +386,9 @@ class COMMAND_HISTORY(objects.StructType): if cmd.is_valid(): yield i, cmd - def get_commands(self): + def get_commands( + self, + ) -> Generator[Tuple[int, interfaces.objects.ObjectInterface], None, None]: """Generator for commands in the history buffer. The CommandBucket is an array of pointers to _COMMAND From 95f56ad122151bf7654dca68f943b7ce5f969f94 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Mon, 7 Oct 2024 12:39:03 -0500 Subject: [PATCH 16/17] #816 - remove extra text from buffer output --- volatility3/framework/plugins/windows/consoles.py | 6 +++++- .../framework/symbols/windows/extensions/consoles.py | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/volatility3/framework/plugins/windows/consoles.py b/volatility3/framework/plugins/windows/consoles.py index cef7cba46..ad1c9d4bd 100644 --- a/volatility3/framework/plugins/windows/consoles.py +++ b/volatility3/framework/plugins/windows/consoles.py @@ -895,7 +895,11 @@ class Consoles(interfaces.plugins.PluginInterface): if console_property["address"] is None else format_hints.Hex(console_property["address"]) ), - str(console_property["data"]), + ( + str(console_property["data"]) + if console_property["data"] + else renderers.NotAvailableValue() + ), ), ) else: diff --git a/volatility3/framework/symbols/windows/extensions/consoles.py b/volatility3/framework/symbols/windows/extensions/consoles.py index 96f7892a5..2312149c7 100644 --- a/volatility3/framework/symbols/windows/extensions/consoles.py +++ b/volatility3/framework/symbols/windows/extensions/consoles.py @@ -192,10 +192,6 @@ class SCREEN_INFORMATION(objects.StructType): if truncate_rows: rows = self._truncate_rows(rows) - if rows: - rows = ["=== START OF BUFFER ==="] + rows + ["=== END OF BUFFER ==="] - else: - rows = ["=== NO BUFFER DATA FOUND ==="] return rows From 1c3e5574f4dda317bfde0fdf72805ca488b342a6 Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Mon, 7 Oct 2024 12:39:58 -0500 Subject: [PATCH 17/17] #816 - remove unused import --- volatility3/framework/plugins/windows/cmdscan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/volatility3/framework/plugins/windows/cmdscan.py b/volatility3/framework/plugins/windows/cmdscan.py index 9a3460a20..9645ee507 100644 --- a/volatility3/framework/plugins/windows/cmdscan.py +++ b/volatility3/framework/plugins/windows/cmdscan.py @@ -6,7 +6,7 @@ import logging import struct -from typing import Tuple, Generator, Set, Dict, Any, List, Optional +from typing import Tuple, Generator, Set, Dict, Any, Optional from volatility3.framework import interfaces from volatility3.framework import renderers