re-windbg

Helps you debug Windows programs by stepping through code and inspecting memory.

Installation
Run `npx skills add "https://github.com/dslsdzc/rev-skills" --skill "re-windbg"` to install this skill, then follow its SKILL.md instructions for my next request.

Paste this into Claude Code, Cursor, or any agent that can run commands.

What this skill does
What it does: - Debugs Windows programs by pausing them, stepping through code line by line, and watching memory and registers change - Analyzes crash dumps to find what went wrong - Debugs Windows drivers and kernel code using two computers or virtual machines - Records program execution and plays it back to find bugs When to use it: - You need to debug a Windows program that is running - You have a crash dump file and want to know why the program failed - You are working with Windows drivers or system-level code - You want to record a program running and replay it to find a hard-to-catch bug
SKILL.mdShow the author's original SKILL.md (not in English)
---
name: re-windbg
description: >
  WinDbg 调试(Windows 用户态+内核)。触发词:WinDbg、windbg、内核调试、kd、!analyze
---

# WinDbg 动态调试(Windows 用户态 + 内核)

## 何时使用 / 何时不用

- 用:Windows 用户态进程调试(启动/附加、断点、单步、寄存器);崩溃/异常分析(`!analyze -v`);内核调试(双机/VM/本地 kd);驱动与内核模块分析(配合 [[re-kernel]]);崩溃 dump(minidump/full dump)分析
- 用:时间旅行调试(TTD)——`ttd.exe` 录制 .run 轨迹后任意回放,适合「复现一次慢慢查」的校验/解密逻辑(见 [[commands]] TTD 节)
- 不用:Linux 目标(走 [[re-gdb]]);macOS 目标([[re-lldb]]);只需轻量 GUI 调试([[re-x64dbg]] 更快)
- 不用:只做静态分析/反编译([[re-ida]] / [[re-ghidra]] / [[re-binaryninja]]);无需与运行态互动的纯静态流程不需要调试器
- 不用:WSL 内跨边界 attach Windows 进程([[platform-tips]] WSL 分支:跨边界走 Windows 侧工具)

## 工具准备

参考 [[platform-tips]] Windows 分支——attach 需要管理员权限;调试属动态执行,默认沙箱内进行([[platform-tips]] 最高原则)。

### WinDbg(微软商店版 / Windows SDK / WDK)

- 商店版(新 UI WinDbg):`winget install Microsoft.WinDbg`(或 Microsoft Store 搜索 "WinDbg")
- 经典版:Windows SDK 安装器勾选 "Debugging Tools for Windows";`choco install windbg`
- WDK(含内核调试工具 kd.exe/kdnet.exe):`winget install Microsoft.WindowsWDK` 或 Visual Studio 安装器勾选 WDK
- 验证: 打开 WinDbg,`File > Open Executable` 加载任意 exe 能停在初始断点;命令窗口 `ver` 输出版本号
- 版本差异: 商店版(WinDbg 1.x,Chromium UI)与经典版(WinDbg 10.0.x)命令兼容,UI 与附加流程不同;dump 分析两者通用(见 [[gotchas]])

### Windows 符号(Windows SDK 符号 / 公共符号服务器)

- 符号路径: `.sympath srv*C:\symbols*https://msdl.microsoft.com/download/symbols`(或设环境变量 `_NT_SYMBOL_PATH`)
- 内核模块符号: 内核调试下 `.reload /f nt`(强制从符号服务器拉取)
- 验证: `!analyze -v` 输出中出现函数名而非 `+0x1a` 裸偏移

### 双机/虚拟机内核调试环境

- 目标机(被调试): `bcdedit /debug on` + `bcdedit /dbgsettings serial debugport:1 baudrate:115200`(串口)或 `bcdedit /dbgsettings net hostip:<宿主机IP> port:50000 key:<kdnet.exe生成的key>`(NET 网卡,Windows 10+ 推荐)
- VM 场景: VMware/Hyper-V 给目标 VM 添加串口设备(Named Pipe `\\.\pipe\com_1` / `-vmconnect`),宿主 WinDbg `File > Kernel Debug > COM` 填管道名
- 本地内核调试(仅测试机,需测试签名): `bcdedit /set testsigning on` 重启后,WinDbg `File > Kernel Debug > Local`
- 验证: 目标机重启停在 "Waiting to reconnect" 或进入调试等待后,宿主 WinDbg 附加成功、`g` 后 `Ctrl+Break` 能中断、`lm` 列出模块

### TTD(时间旅行调试,Windows 10 1903+)

- 录制: `ttd.exe -out C:\traces target.exe`(或 `-attach <pid>` 附加录制;`-monitor <进程名>` 监控启动)
- 打开: WinDbg `File > Open` 选 `.run` 轨迹文件(或 `Open Trace File`)
- 验证: `ttd.exe -help` 有输出;录一段后用 WinDbg 打开,`!tt` 能跳到任意位置、`g-` 能往回跑(详见 [[commands]] TTD 节)

## 操作步骤

1. **附加/启动用户态目标**:
   - 启动: `File > Open Executable` 选目标 exe,停在初始断点(ntdll 加载完成处)
   - 附加: `File > Attach to Process` 按 PID/进程名选目标(**管理员权限**启动 WinDbg 才能附加高权限进程)
   - 命令行: `windbg -p <pid>` / `windbg 目标.exe`;`-g` 跳过初始断点直接运行

2. **断点 / 单步 / 寄存器**:
   - 符号断点: `bp kernel32!CreateFileW`;地址断点: `bp 0x401000`;`bl` 列表、`bd`/`be` 禁用/启用、`bc *` 清空
   - 未加载模块的符号用 `bu`(unresolved,模块加载后自动绑定)——目标 DLL 按需加载时 `bu` 是正解
   - 命令断点: `bp 地址 "r rax; k; gc"`——命中时打印现场后自动继续,日志式观察不打断流程
   - 单步: `g` 继续、`p` 步过、`t` 步入、`gu` 执行到当前函数返回
   - 寄存器: `r` 全部、`r rax` 查看、`r eax=0` 修改(绕过校验常用)
   - 内存/反汇编: `u 0x401000` 反汇编、`dd`/`db` 读内存、`dps rsp` 看栈内容
   - 搜索: `s -d 0x0 L?10000000 0xdeadbeef`(值)、`s -a 0x0 L?10000000 "text"`(ASCII 串)——找硬编码常量/密钥用
   - 符号搜索: `x 模块!*关键字*`(如 `x kernel32!*Virtual*`)——不确定精确符号名时模糊匹配

3. **异常分析 `!analyze -v`**:
   - 目标崩溃停下后: `!analyze -v` → 读 `EXCEPTION_CODE`、`FAULTING_IP`、`STACK_TEXT`、`PROCESS_NAME`
   - 内核蓝屏对应 bugcheck 码(`BUGCHECK_CODE`,如 0xD1 驱动访问无效内存)——先记码再往下查,常见码含义要能对上故障方向
   - 现场恢复: 从 `STACK_TEXT` 取 `EXCEPTION_RECORD` 地址 `.exr <addr>`(异常记录),再取 `CONTEXT` 地址 `.cxr <addr>` 恢复寄存器现场,之后 `k` 出真实调用栈(栈损坏时唯一可靠的栈回溯方式)
   - dump 现场更简单: 打开 dump 后直接 `.ecxr`(自动用异常上下文设寄存器现场)→ `k`——minidump 分析标准开局
   - dump 分析: `File > Open Crash Dump` 打开 `.dmp`(用户态用 `.dump /ma` 生成;内核蓝屏用 `%SystemRoot%\Minidump\*.dmp` 或完全 dump),同样 `!analyze -v` 出 bugcheck 码与故障模块

4. **内核调试(双机 / VM / 本地 kd)**:
   - 目标机配置见「工具准备」;配置后重启,宿主 `File > Kernel Debug` 按所用传输(COM/NET)连接
   - VM 管道串口流程: 目标 VM 加串口 Named Pipe → 目标机 `bcdedit /dbgsettings serial` → 宿主 `File > Kernel Debug > COM` 填管道名(`\\.\pipe\com_1`)→ 目标机重启等连
   - 连接后: `g` 让目标继续跑;`Ctrl+Break` 随时中断回调试器;`!process 0 0` 确认会话活着
   - 本地调试: `bcdedit /set testsigning on` 重启后 `File > Kernel Debug > Local`(仅测试机,不影响生产机的用法)

5. **扩展命令**:
   - `!process 0 0`(全部进程列表)、`!process <EPROCESS> 1`(单进程详情+线程);`.process /p <EPROCESS>` 切到目标进程上下文后再 `k`/`!thread`
   - `!teb`(当前线程 TEB)、`!peb`(当前进程 PEB——命令行、加载模块、环境块)
   - `lm`(模块列表,行尾 `(deferred)`=符号未加载、`(no symbols)`=无符号)、`lmv m <模块>`(版本+路径)、`lmi <模块>`(镜像头)
   - `kv`(带符号完整栈回溯,驱动分析常用)、`!analyze -v` 后按 `STACK_TEXT` 逐帧核对
   - 驱动专项: `lmv m 驱动名` 拿基址 → `.reload /f 驱动名` 加载符号 → 深挖转 [[re-kernel]]

6. **TTD 回放(校验/解密逻辑慢查)**:
   ```
   ttd.exe -out C:\traces target.exe     # 录制
   WinDbg 打开 .run → g- / t- / p-       # 往回跑
   !tt 50                                 # 跳到轨迹 50% 处
   !tt 7213:36                            # 跳指定位置(事件序号:步数)
   ```
   - 断点前移/后移: `!tt br` 在某寄存器值变化处停;`!tt bm` 在内存访问处停
   - 首次打开轨迹先 `!tt.index` 建索引(之后打开跳过);回放中途也可断点 `bp`(在轨迹上工作)
   - 查询 API: `dx @$cursession.TTD.Calls("模块!函数")` 统计调用次数/参数(如 `...Calls("ntdll!mem*")`)
   - TTD 限制: 需管理员运行、用户态专用、轨迹文件很大(数 GB)、回放只读不能写内存(见 [[gotchas]])

7. **伪寄存器与脚本化(简单自动化)**:
   - 伪寄存器: `r $t0 = 0` 起临时变量;`$$ > <文件>` 把命令输出重定向到文件(如 `$$ > c:\log.txt`)
   - 条件执行: `.if (rax==0) { ... } .else { ... }`——配合 `gc` 做断点内逻辑
   - `!runaway` 看线程 CPU 时间(找忙等/死循环线程);`!locks` 查锁状态(挂起排查)

## 跨域联合

- [[re-binary-core]]:工作流第 6 步 Windows 调试器(用户态+内核)
- [[re-kernel]]:内核调试与驱动/rootkit 运行时验证固定调用本技能
- [[re-anti-analysis]]:反调试对抗(内核级检测点)、脱壳后验证
- [[re-malware]]:恶意样本崩溃 dump 分析与内核组件
- [[re-cracking]]:授权校验崩溃定位(`!analyze -v` 快速找崩溃原因)
- 与 [[re-x64dbg]] 互补:轻量 GUI 断点调试用 x64dbg,内核/异常现场恢复/轨迹回放用 WinDbg

## 常见坑与陷阱

- **符号未配置 → 全是裸偏移无函数名**:现象——`lm` 行尾 `(no symbols)`,`k` 输出 `ntdll!+0x1a`;原因——符号路径为空或没 `_NT_SYMBOL_PATH`;对策——`.sympath srv*C:\symbols*https://msdl.microsoft.com/download/symbols` 后 `.reload /f`,内核模块同理(先确认符号服务器可达)
- **内核调试配置错 → 目标机蓝屏死等或连不上**:现象——目标机重启后停在 debug 等待或直接进系统未中断;原因——bcdedit 传输类型/端口与宿主不一致,或物理机单机本地调试受限(PatchGuard);对策——用 VM 串口管道最稳(两边都对 `\\.\pipe\com_1`),`bcdedit /dbgsettings` 重查配置,物理机场景优先 KDNET
- **32/64 位命令与寄存器差异**:现象——64 位目标下 `r eax` 改错值、`!teb` 字段对不上;原因——x64 上下文用 `rax/rbx...`(低 32 位是 `eax` 等)、wow64 目标线程栈在 x86 层;对策——先确认目标位数,wow64 场景 `.load wow64exts` + `!wow64exts.sw` 切到 x86 上下文
- **栈损坏时 `k` 是假象**:现象——调用栈乱(地址不像代码);原因——栈指针被破坏/内存踩踏,常规回溯不可信;对策——用 `.exr` 拿异常记录、`.cxr` 恢复 CONTEXT 后再 `k`,必要时 `!analyze -v` 的 `STACK_TEXT` 里直接取现场
- **蓝屏 dump 打不开**:现象——`Open Crash Dump` 报格式错;原因——minidump 不完整(磁盘满)或用的 32 位 WinDbg 读 64 位 dump;对策——目标机确认内核页交换文件(crash dump 需要 pagefile)足够大,改用同位数 WinDbg
- **RPC 调用统一入口 NdrStubCall3(svchost 功能逆向)**:现象——要拦/分析某个系统功能(如 Toast 通知),不知道它经什么通道进 svchost;原因——功能实现经 RPC 到 svchost 进程,入口难找;对策——Process Monitor 看目标进程加载 rpcrt4.dll + RpcView 确认 RPC 目标进程;**所有 RPC 服务端 stub 统一走 rpcrt4 的 NdrStubCall3**(x64;NdrStubCall2 是旧版 x86,ReactOS/Wine 源码可印证)——在其下断 `kvn` 看调用来源;筛选目标调用:第三参数(r8)指向 RPC_MESSAGE(+0x1C 是 ProcNum 方法编号、+0x28 是接口描述指针 RpcInterfaceInformation → RPC_SERVER_INTERFACE 的 InterfaceId 在 +0x04);**opnum 由 MIDL 按方法声明顺序从 0 编号**(如 PostNotification3 排第 0x29 位 → opnum=0x29),ObjectStublessClientN 中 rax=N 即 ProcNum;坑:NdrStubCall3 处理 svchost 内所有 RPC 接口,**必须按 InterfaceId + ProcNum 双重筛选**,只拦目标方法(拦错会把 Edge 等其他功能搞挂)
- TTD 限制、版本差异与符号服务器细节见 [[gotchas]]

Ships with 2 supporting files:

  • references/commands.md
  • references/gotchas.md

Mirrored from the author's public source. Install counts from the open skills registry.

The systems behind these skills get built for partners every week.

Partner with us