memoryforensics1/windbg-mcp

GitHub: memoryforensics1/windbg-mcp

一个C#实现的MCP服务器,为AI代理提供Windows内核和用户态调试的自动化控制,通过直接集成DbgEng和VMware提升稳定性。

Stars: 15 | Forks: 1

# WinDbg MCP 服务器 一个[模型上下文协议](https://modelcontextprotocol.io/) (MCP) 服务器,为 AI 代理提供对 Windows 虚拟机的完全控制权,用于内核调试、逆向工程、恶意软件分析和漏洞研究。 使用 C# (.NET 8) 构建,它将 Windows 调试引擎(DbgEng COM)、VMware Workstation、Frida 和 dbgsrv 封装成 **29 个 MCP 工具**,任何兼容 MCP 的 LLM 客户端均可调用。 ![Architecture](https://img.shields.io/badge/.NET_8-512BD4?logo=dotnet&logoColor=white) ![Platform](https://img.shields.io/badge/Windows-0078D6?logo=windows&logoColor=white) ![VMware](https://img.shields.io/badge/VMware_Workstation-607078?logo=vmware&logoColor=white) ![License](https://img.shields.io/badge/license-MIT-green) ## 为什么有这个项目? 其他 WinDbg MCP 服务器已经存在——大多数是启动 `cdb.exe` 或 `windbg.exe` 作为子进程并通过 stdin/stdout 驱动的 Python 封装。这很容易原型化,但在实践中很脆弱:子调试器会崩溃、在模态对话框上挂起、使自身管道死锁,或在会话中途死亡并带走代理的上下文。 本项目采用了不同的方法: - **直接使用 DbgEng COM** —— 通过其 COM 接口原生调用 Windows 调试引擎。无需管理子进程,无需解析 stdout,没有挂起的管道。命令在服务器进程中执行,位于一个带有事件泵的专用 MTA COM 线程上——因此调试器无法拖垮整个 MCP 服务器。 - **内核调试是主要用例,而非事后补充** —— 完整的 KDNET 集成:附加到运行中的内核、设置断点、单步执行、在目标挂起时运行任何 WinDbg 命令、等待带硬超时的事件、检测蓝屏,并通过传递首次机会异常使 Windows 继续正常运行。执行控制命令(`g`/`t`/`p`)在 `kd_execute` 中被阻止,因此 LLM 无法意外地从断点处继续运行——它必须使用显式的 `kd_continue`/`kd_step` 工具,这些工具总会返回。 - **用户模式也被覆盖** —— Frida(带有永恒钩子,用于跨会话的持久化插桩)、用于非侵入性进程检查的 dbgsrv(可访问完整的 WinDbg 命令)以及 TTD(时间旅行调试)——都位于同一服务器之后。 - **虚拟机生命周期与调试会话集成** —— 快照恢复会先干净地拆卸 KD/Frida/dbgsrv,然后再还原虚拟机;客户机命令、文件传输和进程控制都基于虚拟机电源状态进行门控,这样代理永远不会遇到“状态错误”的提示。`vm_set_target` 允许运行中的服务器在运行时切换到不同的虚拟机。 - **专为 LLM 代理设计** —— 每个工具都有硬超时(没有无限阻塞),每条错误消息都明确告知 LLM 下一步该做什么,并且 `get_system_state` 按需为模型提供单个“我在哪里?”的快照。`StateCoordinator` 在每次调用前验证前置条件,因此代理获得的是有用的反馈,而不是静默失败。 ## 它能做什么? 连接到此服务器的 LLM 可以自主地: - **控制虚拟机** —— 启动、停止、暂停、恢复、快照、恢复、截图 - **内核调试** —— 通过 KDNET 连接、设置断点、单步执行、执行任何 WinDbg 命令、等待事件 - **在客户机中运行命令** —— 执行程序、传输文件、列出/终止进程 - **用户模式调试** —— 附加 Frida 以钩子函数、通过 dbgsrv 检查进程、记录 TTD 跟踪 整个过程 LLM 无需直接访问 WinDbg、终端或虚拟机本身。 ## 快速开始 ### 前置条件 | 要求 | 用途 | |---|---| | [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) | 构建并运行服务器 | | [VMware Workstation Pro](https://www.vmware.com/products/workstation-pro.html) | 虚拟机管理 (vmrun) | | Windows 客户机虚拟机 | 调试目标 | | 客户机中启用 KDNET | 内核调试(参见[设置](#vm-setup)) | | [frida-tools](https://frida.re/) *(可选)* | 用户模式插桩 | | [WinDbg Preview](https://aka.ms/windbg) *(可选)* | 提供用于远程用户模式调试的 dbgsrv.exe | ### 1. 克隆并构建 ``` git clone https://github.com/memoryforensics1/windbg-mcp.git cd windbg-mcp dotnet build src/WinDbgMCP.Server/WinDbgMCP.Server.csproj ``` ### 2. 配置 *(可选)*
appsettings.json 中的所有内容都只是默认值——LLM 可以在运行时通过 vm_set_target 更改虚拟机目标、凭据、KDNET 密钥等。仅当您想设置初始配置时才展开。 将 `src/WinDbgMCP.Server/appsettings.example.json` 复制到 `appsettings.json` 并编辑: ``` { "Vm": { "VmxPath": "C:\\path\\to\\your\\vm.vmx", "VmrunPath": "C:\\Program Files (x86)\\VMware\\VMware Workstation\\vmrun.exe", "VmPassword": "", "GuestUsername": "YourUser", "GuestPassword": "YourPass" }, "KernelDebug": { "Transport": "kdnet", "Kdnet": { "Port": 50000, "Key": "your.kdnet.key.here" }, "SymbolPath": "srv*C:\\Symbols*https://msdl.microsoft.com/download/symbols" }, "Guest": { "FridaPort": 27042, "DbgsrvPort": 5064 } } ```
### 3. 添加到您的 MCP 客户端 **Claude Code**(项目根目录下的 `.mcp.json`): ``` { "mcpServers": { "windbg-mcp": { "command": "dotnet", "args": ["run", "--project", "C:\\path\\to\\windbg-mcp\\src\\WinDbgMCP.Server\\WinDbgMCP.Server.csproj"] } } } ``` **Claude Desktop**(`claude_desktop_config.json`): ``` { "mcpServers": { "windbg-mcp": { "command": "C:\\Program Files\\dotnet\\dotnet.exe", "args": ["run", "--project", "C:\\path\\to\\windbg-mcp\\src\\WinDbgMCP.Server\\WinDbgMCP.Server.csproj"] } } } ``` ### 4. 运行 当您的 MCP 客户端连接时,服务器会自动启动。它通过 stdio 进行通信。 ``` # 或独立运行以进行测试 dotnet run --project src/WinDbgMCP.Server/WinDbgMCP.Server.csproj ``` ## 工具目录 (29 个工具) ### 元数据 | 工具 | 描述 | |---|---| | `get_system_state` | 完整状态概览——虚拟机电源、KD、客户机操作、UMD。始终允许。 | ### 虚拟机工具 (8 个) | 工具 | 描述 | |---|---| | `vm_start` | 启动虚拟机电源 | | `vm_stop` | 关机(优雅或强制) | | `vm_pause` | 冻结整个虚拟机 | | `vm_resume` | 恢复已暂停的虚拟机 | | `vm_snapshot_restore` | 恢复命名快照(调试会话会被干净拆卸,之后可以重新连接) | | `vm_snapshot_list` | 列出可用快照 | | `vm_screenshot` | 将虚拟机显示捕获为 PNG | | `vm_set_target` | 在运行时切换活动的虚拟机目标(VMX 路径 + 凭据) | ### 内核调试工具 (7 个) | 工具 | 描述 | |---|---| | `kd_connect` | 通过 KDNET 附加到内核。连接时目标会中断。 | | `kd_disconnect` | 从内核分离。恢复目标运行,使虚拟机继续运行。 | | `kd_break` | 挂起运行中的目标 (Ctrl+Break) | | `kd_continue` | 恢复目标执行 | | `kd_step` | 单步执行一条指令(进入或越过) | | `kd_execute` | 运行任何 WinDbg 命令(`k`, `r`, `lm`, `!process 0 0`, `!analyze -v` 等) | | `kd_wait_for_event` | 带超时等待断点/异常。总会返回。 | ### 客户机工具 (5 个) | 工具 | 描述 | |---|---| | `guest_run_command` | 在客户机操作系统中执行命令,捕获 stdout/stderr | | `guest_transfer_to_vm` | 将文件从主机复制到客户机 | | `guest_transfer_from_vm` | 将文件从客户机复制到主机 | | `guest_list_processes` | 列出正在运行的进程及其 PID | | `guest_kill_process` | 通过 PID 终止进程 | ### 用户模式调试工具 (8 个) | 工具 | 描述 | |---|---| | `umd_frida_attach` | 将 Frida 附加到客户机进程 | | `umd_frida` | 注入 JS,求值表达式,列出进程,分离 | | `umd_frida_skill` | 适用于 LLM 的 Frida 最佳实践和 API 参考 | | `umd_dbgsrv_connect` | 连接到客户机中的远程 dbgsrv | | `umd_dbgsrv_execute` | 附加到 PID,运行 WinDbg 命令,分离 | | `umd_dbgsrv_skill` | 适用于 LLM 的 dbgsrv 最佳实践和 WinDbg 命令参考 | | `umd_ttd` | 时间旅行调试——录制、停止、检索、列出跟踪 | | `umd_ttd_query` | 查询 TTD 跟踪 *(尚未实现)* | ## 示例工作流 ### 检查运行中的内核 ``` get_system_state kd_connect kd_execute("lm") # list loaded modules kd_execute("!process 0 0") # list all processes kd_execute("vertarget") # target version info kd_disconnect ``` ### 设置断点并捕获 ``` kd_connect kd_execute("bp nt!NtCreateFile") # set breakpoint kd_continue # let target run kd_wait_for_event(30) # wait up to 30s for hit kd_execute("k") # show call stack kd_execute("r") # show registers kd_disconnect ``` ### 部署并调试驱动程序 ``` guest_transfer_to_vm("MyDriver.sys", "C:\\Windows\\System32\\drivers\\MyDriver.sys") guest_run_command("sc create MyDrv type= kernel binPath= C:\\Windows\\System32\\drivers\\MyDriver.sys") guest_run_command("sc start MyDrv") kd_connect kd_execute("lm m MyDrv") # verify driver loaded kd_execute("bp MyDrv!DriverEntry") kd_disconnect ``` ### 使用 Frida 钩子函数 ``` umd_frida_skill # read best practices first umd_frida_attach(processName="target.exe") umd_frida(action="eval", code="Process.enumerateModules().map(m=>m.name)") umd_frida(action="inject", code=""" Interceptor.attach(Module.getExportByName('kernel32.dll','CreateFileW'), { onEnter(args) { console.log('CreateFileW: ' + args[0].readUtf16String()); } }); console.log('Hook installed'); """, timeoutSeconds=10) umd_frida(action="detach") ``` ### 使用 dbgsrv 检查进程 ``` umd_dbgsrv_skill # read best practices first guest_run_command("start /b C:\\Tools\\DbgSrv\\dbgsrv.exe -t tcp:port=5064") umd_dbgsrv_connect(vmIpAddress="192.168.x.x") umd_dbgsrv_execute(action="attach", argument="") umd_dbgsrv_execute(action="command", argument="lm") umd_dbgsrv_execute(action="command", argument="!peb") umd_dbgsrv_execute(action="command", argument="~*k") umd_dbgsrv_execute(action="detach") umd_dbgsrv_execute(action="disconnect") ``` ### 崩溃分析 ``` kd_connect # connect after BSOD kd_execute("!analyze -v") # automated crash analysis kd_execute("k") # faulting stack kd_execute("r") # registers at crash kd_execute(".trap") # switch to trap frame kd_disconnect ``` ## 架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ MCP Client (LLM) │ │ Claude Code / Claude Desktop │ └──────────────────────────┬──────────────────────────────────┘ │ stdio (JSON-RPC) ┌──────────────────────────▼──────────────────────────────────┐ │ WinDbgMCP.Server │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ VM Tools │ │ KD Tools │ │ Guest Tools │ │ │ │ (vmrun) │ │ (DbgEng) │ │ (vmrun guest) │ │ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────────┘ │ │ │ │ │ │ │ ┌──────▼───────┐ ┌──────▼───────┐ ┌──────▼───────────┐ │ │ │ VmwareManager│ │ DbgEngManager│ │ GuestExecManager │ │ │ └──────────────┘ └──────┬───────┘ └──────────────────┘ │ │ │ │ │ ┌────────────────────────▼─────────────────────────────┐ │ │ │ StateCoordinator │ │ │ │ (precondition gate — validates every tool call) │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ UMD: Frida │ │ UMD: dbgsrv │ │ UMD: TTD │ │ │ │ (frida CLI) │ │ (DbgEng COM) │ │ (TTD.exe) │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ └──────────────────────────────────────────────────────────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Windows Guest VM │ │ (VMware Workstation Pro) │ │ │ │ KDNET (:50000) │ frida-server (:27042) │ dbgsrv (:5064)│ └─────────────────────────────────────────────────────────────┘ ``` ### 关键设计原则 1. **每个工具都验证前置条件** —— `StateCoordinator` 在任何操作执行前检查虚拟机电源、KD 状态、客户机操作可用性 2. **每个操作都有超时** —— 永无阻塞调用。LLM 永远不会挂起。 3. **错误消息即提示** —— 每个错误都明确告知 LLM 下一步该做什么 4. **执行控制命令被阻止** —— `g`, `t`, `p` 在 `kd_execute` 中被阻止;请使用 `kd_continue`/`kd_step` 代替 5. **DbgEng COM 线程亲和性** —— 所有 COM 调用都编组到带有事件泵的专用 MTA 线程 6. **蓝屏检测** —— 错误检查被检测并以不同于普通断点的方式处理 7. **快照恢复重置一切** —— KD、Frida、dbgsrv 会话都会被清理 ## 虚拟机设置 ### 启用 KDNET(内核调试) 在客户机虚拟机中(以管理员身份运行 cmd): ``` bcdedit /debug on bcdedit /dbgsettings net hostip: port:50000 key: shutdown /r /t 0 ``` 使用 Windows SDK 中的 `kdnet.exe` 生成密钥,或使用任何点分四格式的密钥。 ### 安装 Frida 服务器(可选) 在**主机**上: ``` pip install frida-tools ``` 从 [Frida 发布版](https://github.com/frida/frida/releases) 下载 `frida-server--windows-x86_64.exe`,部署到客户机作为 `C:\Tools\frida-server.exe`,然后运行: ``` frida-server.exe -l 0.0.0.0:27042 ``` ### 安装 dbgsrv(可选) 将 `dbgsrv.exe`、`dbgeng.dll` 和 `dbghelp.dll` 从 WinDbg Preview(或 Windows SDK)复制到客户机,然后运行: ``` dbgsrv.exe -t tcp:port=5064 ``` ### 防火墙 主机防火墙必须允许: - UDP 端口 50000 入站 (KDNET) - TCP 端口 27042 出站 (Frida) - TCP 端口 5064 出站 (dbgsrv) ## 项目结构 ``` src/WinDbgMCP.Server/ ├── Program.cs # Entry point, MCP server setup, DI ├── appsettings.json # Configuration (VM creds, KDNET, timeouts) ├── Configuration/ │ └── ServerConfig.cs # Typed configuration model ├── State/ │ ├── SystemState.cs # State model + enums │ ├── StateCoordinator.cs # Precondition gate (heart of system) │ ├── ErrorMessages.cs # LLM-friendly error catalog │ └── ToolResult.cs # Result type ├── Vmware/ │ └── VmwareManager.cs # vmrun wrapper ├── KernelDebug/ │ ├── DbgEngThread.cs # Dedicated MTA thread for COM │ ├── DbgEngManager.cs # Kernel debug session manager │ ├── DebugEventCallbacks.cs # Breakpoint/exception/module events │ ├── OutputCapture.cs # Command output capture │ └── Interop/ # P/Invoke, constants ├── Guest/ │ └── GuestExecManager.cs # Guest command execution + file transfer ├── UserModeDebug/ │ ├── FridaManager.cs # Frida CLI wrapper │ ├── DbgsrvManager.cs # Remote user-mode debugging via dbgsrv │ └── TtdManager.cs # Time Travel Debugging └── Tools/ ├── VmTools.cs # vm_* tools ├── KernelDebugTools.cs # kd_* tools ├── GuestTools.cs # guest_* tools ├── UserModeDebugTools.cs # umd_* tools └── MetaTools.cs # get_system_state src/WinDbgMCP.Tests/ # Unit tests (126 tests) ``` ## 运行测试 ``` dotnet test src/WinDbgMCP.Tests/WinDbgMCP.Tests.csproj ``` ## 技术栈 | 组件 | 技术 | |---|---| | 运行时 | .NET 8 (C#) | | MCP SDK | [ModelContextProtocol](https://github.com/modelcontextprotocol/csharp-sdk) 0.1.0-preview.12 | | DbgEng | 原生 COM 互操作 (`dbgeng.dll`) | | 虚拟机控制 | VMware vmrun CLI | | 用户模式钩子 | Frida (frida-tools Python CLI) | | 远程调试 | dbgsrv.exe (WinDbg 组件) | | TTD | TTD.exe (时间旅行调试) | ## 许可证 MIT
标签:AI代理调试, BSOD检测, C#编程, DAST, DbgEng接口, dbgsrv调试服务, Frida动态插桩, KDNET网络调试, LLM工具集成, MCP协议, .NET框架, TLS抓取, TTD时间旅行调试, VMware虚拟化, Windows系统, 云资产清单, 内核调试, 分布式计算, 威胁情报, 开发者工具, 异常处理, 性能分析, 恶意软件分析, 情报收集, 执行控制, 断点管理, 漏洞研究, 用户模式调试, 网络安全, 虚拟机控制, 调试, 调试命令, 软件安全, 逆向工程, 隐私保护