Windows内核安全

1、配置双机调试环境

1、课程目标

  1. 理解内核调试的基本概念和原理
  2. 掌握VMware虚拟机双机调试配置
  3. 学会使用WinDbg进行内核调试
  4. 熟悉常用内核调试命令

2、名词解释

术语 解释
Ring0 CPU最高特权级,内核模式运行级别
Ring3 用户模式运行级别
KD Kernel Debugger,内核调试器
双机调试 使用两台机器进行内核调试的方式
串口调试 通过COM口进行调试通信
命名管道调试 VMware通过命名管道模拟串口

3、使用工具

工具 用途
VMware Workstation 虚拟化平台
WinDbg 内核调试器
VirtualKD 加速虚拟机调试
bcdedit 配置启动选项

4、技术原理

4.1、双机调试架构

┌─────────────────────────────────────────────────────────────┐
│                      双机调试架构                            │
│                                                             │
│   主机(Host)                    虚拟机(Guest)            │
│   ┌──────────────┐               ┌──────────────┐          │
│   │   WinDbg     │               │  被调试系统   │          │
│   │  (Debugger)  │←─────────────→│   (Debugee)  │          │
│   └──────────────┘   命名管道    └──────────────┘          │
│        ↑              \\.\pipe\    调试引擎内置           │
│        │              com_1        于Windows内核           │
│   调试符号(.pdb)                                           │
│   源代码                                                    │
└─────────────────────────────────────────────────────────────┘

4.2、调试通信方式对比

方式 速度 配置难度 适用场景
串口(COM) 简单 物理双机
1394火线 中等 物理双机
USB 3.0 中等 物理双机
命名管道 中等 简单 VMware
网络调试 复杂 远程调试

5、配置步骤

5.1、步骤1:VMware虚拟机配置

1. 关闭虚拟机
2. 编辑虚拟机设置 → 添加 → 串行端口
3. 选择"输出到命名管道"
4. 配置:
   - 命名管道:\\.\pipe\com_1
   - 连接:该端是服务器
   - 另一端:应用程序

5. 在.vmx文件中添加(可选,加速):
   serial0.present = "TRUE"
   serial0.fileType = "pipe"
   serial0.fileName = "\\.\pipe\com_1"
   serial0.tryNoRxLoss = "TRUE"
   serial0.pipe.endPoint = "server"

5.2、步骤2:被调试系统配置

:: 以管理员权限运行

:: 开启调试模式
bcdedit /debug on

:: 设置调试类型为串口
bcdedit /dbgsettings serial debugport:1 baudrate:115200

:: 禁用驱动签名(开发测试)
bcdedit /set testsigning on

:: 查看当前配置
bcdedit /dbgsettings

:: 重启生效
shutdown /r /t 0

5.3、步骤3:WinDbg连接配置

1. 启动WinDbg(以管理员权限)
2. File → Kernel Debug(Ctrl+K)
3. 选择COM选项卡
4. 配置:
   - Baud Rate: 115200
   - Port: \\.\pipe\com_1
   - 勾选 Pipe
   - 勾选 Reconnect

5. 点击OK开始连接
6. 启动虚拟机,WinDbg自动连接

6、代码实现

6.1、示例1:WinDbg常用命令

# ==================== 基础命令 ====================

# 中断执行
Ctrl+Break

# 继续执行
g

# 单步步入
t

# 单步步过
p

# 查看寄存器
r

# 查看调用栈
k
kb      # 带参数
kv      # 详细信息
kp      # 显示完整参数

# ==================== 内存操作 ====================

# 显示内存(字节)
db <address> L<length>

# 显示内存(双字)
dd <address>

# 显示内存(四字)
dq <address>

# 显示内存(ASCII字符串)
da <address>

# 显示内存(Unicode字符串)
du <address>

# 修改内存
eb <address> <value>    # 写字节
ed <address> <value>    # 写双字

# 搜索内存
s -b <start> L<length> <pattern>
s -a <start> L<length> "string"

# ==================== 断点命令 ====================

# 设置断点
bp <address>
bp <module>!<function>
bp nt!NtCreateFile

# 条件断点
bp nt!NtOpenProcess ".if (@rcx == 0x1234) {} .else {gc}"

# 硬件断点(写入)
ba w4 <address>

# 硬件断点(执行)
ba e1 <address>

# 列出断点
bl

# 删除断点
bc <id>
bc *        # 删除所有

# 禁用/启用断点
bd <id>
be <id>

# ==================== 符号和模块 ====================

# 重新加载符号
.reload

# 加载指定模块符号
.reload /f <module>

# 设置符号路径
.sympath srv*c:\symbols*https://msdl.microsoft.com/download/symbols

# 查看模块列表
lm

# 查看模块详情
lm v m <module>

# 查看符号
x <module>!<pattern>
x nt!Nt*

# ==================== 进程线程 ====================

# 列出进程
!process 0 0

# 查看指定进程详情
!process <EPROCESS> 7

# 切换进程上下文
.process /i <EPROCESS>

# 列出线程
!thread

# 查看线程详情
!thread <ETHREAD>

# ==================== 系统信息 ====================

# 查看系统版本
vertarget

# 查看KPCR
!pcr

# 查看IDT
!idt

# 查看GDT
!gdt

# 查看系统调用表
dps nt!KiServiceTable L<count>

6.2、示例2:调试脚本

// debug_script.txt - WinDbg调试脚本

// 设置符号路径
.sympath srv*c:\symbols*https://msdl.microsoft.com/download/symbols

// 加载内核符号
.reload /f nt

// 开启详细输出
!sym noisy

// 设置常用断点
bp nt!NtCreateFile
bp nt!NtOpenProcess
bp nt!NtReadVirtualMemory
bp nt!NtWriteVirtualMemory

// 设置日志断点(不中断)
bp nt!NtCreateFile ".printf \"NtCreateFile called\\n\"; gc"

// 运行脚本: $$><debug_script.txt

6.3、示例3:VirtualKD加速调试

:: VirtualKD 安装步骤

:: 1. 下载VirtualKD-Redux
:: https://github.com/4d61726b/VirtualKD-Redux

:: 2. 在虚拟机中运行target\vminstall.exe
:: 3. 选择安装调试引导项
:: 4. 重启虚拟机

:: 5. 在主机运行vmmon64.exe
:: 6. 启动虚拟机,选择VirtualKD启动项
:: 7. vmmon自动启动WinDbg并连接

:: 速度对比:
:: - 原生串口:~115200 bps
:: - VirtualKD:~150 MB/s(提升1000倍)

6.4、示例4:网络调试配置

:: Windows 8及以上支持网络调试

:: 被调试机配置
bcdedit /debug on
bcdedit /dbgsettings net hostip:192.168.1.100 port:50000

:: 会显示一个Key,需要记录
:: Key=1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16

:: WinDbg连接
:: File → Kernel Debug → NET
:: Port: 50000
:: Key: <上面生成的Key>

6.5、示例5:常用调试场景

// ==================== 场景1:分析蓝屏 ====================

// 加载dump文件
File → Open Crash Dump

// 自动分析
!analyze -v

// 查看崩溃调用栈
.trap <trap_frame>
kv

// ==================== 场景2:驱动调试 ====================

// 在驱动入口设断点
bu MyDriver!DriverEntry

// 查看驱动对象
!drvobj MyDriver

// 查看设备对象
!devobj <DEVICE_OBJECT>

// ==================== 场景3:查找隐藏进程 ====================

// 遍历活动进程链表
!process 0 0

// 获取PsActiveProcessHead
? nt!PsActiveProcessHead

// 手动遍历
dt nt!_EPROCESS <address> ActiveProcessLinks

// ==================== 场景4:SSDT分析 ====================

// 获取SSDT基址
dps nt!KiServiceTable L100

// 查看特定服务号
dps nt!KiServiceTable+8*<index> L1

// 检测HOOK
!chkimg nt -d

7、课后作业

  1. 配置VMware+WinDbg双机调试环境
  2. 安装VirtualKD并验证调试速度提升
  3. 练习使用WinDbg查看进程、线程、模块信息
  4. 编写一个调试脚本自动设置常用断点

8、扩展阅读

  • WinDbg官方文档
  • Windows Internals
  • Advanced Windows Debugging (Mario Hewardt)