Source code for volatility3.plugins.windows.kpcrs

# 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
#

import logging

from typing import Iterator, Generator, List, Tuple

from volatility3.framework import (
    renderers,
    interfaces,
    constants,
)
from volatility3.framework.configuration import requirements
from volatility3.framework.objects import utility
from volatility3.framework.renderers import format_hints

vollog = logging.getLogger(__name__)


[docs] class KPCRs(interfaces.plugins.PluginInterface): """Print KPCR structure for each processor""" _required_framework_version = (2, 0, 0) _version = (2, 0, 0)
[docs] @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: return [ requirements.ModuleRequirement( name="kernel", description="Windows kernel", architectures=["Intel32", "Intel64"], ), ]
[docs] @classmethod def list_kpcrs( cls, context: interfaces.context.ContextInterface, kernel_module_name: str, ) -> Generator[Tuple[interfaces.objects.ObjectInterface, int], None, None]: """Returns the KPCR structure for each processor Args: context: The context to retrieve required elements (layers, symbol tables) from kernel_module_name: The name of the kernel module on which to operate Returns: The _KPCR structure for each processor """ kernel = context.modules[kernel_module_name] kernel_layer = context.layers[kernel.layer_name] kpcr_type = kernel.get_type("_KPCR") reloff = kpcr_type.relative_child_offset("Prcb") if kpcr_type.has_member("CurrentPrcb"): kpcr_member = "CurrentPrcb" else: kpcr_member = "Prcb" cpu_count_offset = kernel.get_symbol("KeNumberProcessors").address cpu_count = kernel.object( object_type="unsigned int", layer_name=kernel_layer.name, offset=cpu_count_offset, ) processor_block = kernel.object( object_type="pointer", layer_name=kernel_layer.name, offset=kernel.get_symbol("KiProcessorBlock").address, ) processor_pointers = utility.array_of_pointers( context=context, array=processor_block, count=cpu_count, subtype=kernel.symbol_table_name + constants.BANG + "_KPRCB", ) for pointer in processor_pointers: kprcb = pointer.dereference() object_address = kprcb.vol.offset - reloff if not kernel_layer.is_valid(kprcb.vol.offset): continue kpcr = kernel.object("_KPCR", offset=object_address, absolute=True) yield kpcr, kpcr.member(kpcr_member)
def _generator(self) -> Iterator[Tuple]: for kpcr, current_prcb in self.list_kpcrs(self.context, self.config["kernel"]): yield ( 0, ( format_hints.Hex(kpcr.vol.offset), format_hints.Hex(current_prcb), ), )
[docs] def run(self): return renderers.TreeGrid( [ ("Offset", format_hints.Hex), ("PRCB Offset", format_hints.Hex), ], self._generator(), )