Beispiel #1
0
    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")
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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