def recurse_symbol_fulfiller( self, context: interfaces.context.ContextInterface, valid_kernel: ValidKernelType, progress_callback: constants.ProgressCallback = None) -> None: """Fulfills the SymbolTableRequirements in `self._symbol_requirements` found by the `recurse_symbol_requirements`. This pass will construct any requirements that may need it in the context it was passed Args: context: Context on which to operate valid_kernel: A list of offsets where valid kernels have been found """ for sub_config_path, requirement in self._symbol_requirements: # TODO: Potentially think about multiple symbol requirements in both the same and different levels of the requirement tree # TODO: Consider whether a single found kernel can fulfill multiple requirements if valid_kernel: # TODO: Check that the symbols for this kernel will fulfill the requirement virtual_layer, _kvo, kernel = valid_kernel if not isinstance(kernel['pdb_name'], str) or not isinstance( kernel['GUID'], str): raise TypeError("PDB name or GUID not a string value") PDBUtility.load_windows_symbol_table( context=context, guid=kernel['GUID'], age=kernel['age'], pdb_name=kernel['pdb_name'], symbol_table_class= "volatility3.framework.symbols.windows.WindowsKernelIntermedSymbols", config_path=sub_config_path, progress_callback=progress_callback) else: vollog.debug("No suitable kernel pdb signature found")
def check_kernel_offset( self, context: interfaces.context.ContextInterface, vlayer: layers.intel.Intel, address: int, progress_callback: constants.ProgressCallback = None ) -> Optional[ValidKernelType]: """Scans a virtual address.""" # Scan a few megs of the virtual space at the location to see if they're potential kernels valid_kernel = None # type: Optional[ValidKernelType] kernel_pdb_names = [ bytes(name + ".pdb", "utf-8") for name in constants.windows.KERNEL_MODULE_NAMES ] virtual_layer_name = vlayer.name try: if vlayer.read(address, 0x2) == b'MZ': res = list( PDBUtility.pdbname_scan( ctx=context, layer_name=vlayer.name, page_size=vlayer.page_size, pdb_names=kernel_pdb_names, progress_callback=progress_callback, start=address, end=address + self.max_pdb_size)) if res: valid_kernel = (virtual_layer_name, address, res[0]) except exceptions.InvalidAddressException: pass return valid_kernel
def _method_layer_pdb_scan( self, context: interfaces.context.ContextInterface, vlayer: layers.intel.Intel, test_kernel: Callable, physical: bool = True, progress_callback: constants.ProgressCallback = None ) -> Optional[ValidKernelType]: # TODO: Verify this is a windows image valid_kernel = None virtual_layer_name = vlayer.name physical_layer_name = self.get_physical_layer_name(context, vlayer) layer_to_scan = physical_layer_name if not physical: layer_to_scan = virtual_layer_name kernel_pdb_names = [ bytes(name + ".pdb", "utf-8") for name in constants.windows.KERNEL_MODULE_NAMES ] kernels = PDBUtility.pdbname_scan(ctx=context, layer_name=layer_to_scan, page_size=vlayer.page_size, pdb_names=kernel_pdb_names, progress_callback=progress_callback) for kernel in kernels: valid_kernel = test_kernel(physical_layer_name, virtual_layer_name, kernel) if valid_kernel is not None: break return valid_kernel
def method_fixed_mapping( self, context: interfaces.context.ContextInterface, vlayer: layers.intel.Intel, progress_callback: constants.ProgressCallback = None ) -> Optional[ValidKernelType]: # TODO: Verify this is a windows image vollog.debug("Kernel base determination - testing fixed base address") valid_kernel = None virtual_layer_name = vlayer.name physical_layer_name = self.get_physical_layer_name(context, vlayer) kernel_pdb_names = [ bytes(name + ".pdb", "utf-8") for name in constants.windows.KERNEL_MODULE_NAMES ] kernels = PDBUtility.pdbname_scan(ctx=context, layer_name=physical_layer_name, page_size=vlayer.page_size, pdb_names=kernel_pdb_names, progress_callback=progress_callback) for kernel in kernels: # It seems the kernel is loaded at a fixed mapping (presumably because the memory manager hasn't started yet) if kernel['mz_offset'] is None or not isinstance( kernel['mz_offset'], int): # Rule out kernels that couldn't find a suitable MZ header continue if vlayer.bits_per_register == 64: kvo = kernel['mz_offset'] + (31 << int( math.ceil(math.log2(vlayer.maximum_address + 1)) - 5)) else: kvo = kernel['mz_offset'] + (1 << (vlayer.bits_per_register - 1)) try: kvp = vlayer.mapping(kvo, 0) if (any([(p == kernel['mz_offset'] and layer_name == physical_layer_name) for (_, _, p, _, layer_name) in kvp])): valid_kernel = (virtual_layer_name, kvo, kernel) break else: vollog.debug( "Potential kernel_virtual_offset did not map to expected location: {}" .format(hex(kvo))) except exceptions.InvalidAddressException: vollog.debug( "Potential kernel_virtual_offset caused a page fault: {}". format(hex(kvo))) return valid_kernel
def _method_layer_pdb_scan( self, context: interfaces.context.ContextInterface, vlayer: layers.intel.Intel, test_kernel: Callable, optimized: bool = False, physical: bool = True, progress_callback: constants.ProgressCallback = None ) -> Optional[ValidKernelType]: # TODO: Verify this is a windows image valid_kernel = None virtual_layer_name = vlayer.name physical_layer_name = self.get_physical_layer_name(context, vlayer) layer_to_scan = physical_layer_name if not physical: layer_to_scan = virtual_layer_name start_scan_address = 0 if optimized and not physical and context.layers[ layer_to_scan].metadata.architecture in ["Intel64"]: # TODO: change this value accordingly when 5-Level paging is supported. start_scan_address = (0x1f0 << 39) kernel_pdb_names = [ bytes(name + ".pdb", "utf-8") for name in constants.windows.KERNEL_MODULE_NAMES ] kernels = PDBUtility.pdbname_scan(ctx=context, layer_name=layer_to_scan, start=start_scan_address, page_size=vlayer.page_size, pdb_names=kernel_pdb_names, progress_callback=progress_callback) for kernel in kernels: valid_kernel = test_kernel(physical_layer_name, virtual_layer_name, kernel) if valid_kernel is not None: break return valid_kernel