notgate/dnSpy-MCP
GitHub: notgate/dnSpy-MCP
一个基于 .NET 8 与 dnSpyEx 的静态 MCP 调试服务器,专为程序集元数据、反编译与保护分析而设计。
Stars: 9 | Forks: 1
# dnSpy-MCP
一个用于静态 .NET 程序集分析的模型上下文协议(MCP)服务器,由 ICSharpCode.Decompiler(dnSpyEx 引擎)提供支持。将反编译、IL 反汇编、元数据检查和保护分析作为 MCP 工具通过 stdio 暴露。永远不会执行目标程序集。
## 要求
- .NET 8 SDK 或更高版本
- 兼容的 MCP 客户端(Claude Desktop、Cursor 或任何支持 MCP stdio 传输的客户端)
## 安装
```
git clone https://github.com/ZeraTS/dnSpy-MCP.git
cd dnSpy-MCP
dotnet build src/DnSpyMcp/DnSpyMcp.csproj -c Release
```
## Claude Desktop 配置
添加到 `claude_desktop_config.json`:
```
{
"mcpServers": {
"dnspy-mcp": {
"command": "dotnet",
"args": ["/path/to/src/DnSpyMcp/bin/Release/net8.0/DnSpyMcp.dll"]
}
}
}
```
## 工具
| 工具 | 描述 | 关键参数 |
|------|-------------|----------------|
| `get_pe_info` | 获取 PE/COFF 头信息、程序集元数据和目标框架 | `assemblyPath` |
| `get_resources` | 列出程序集中嵌入的所有清单资源 | `assemblyPath` |
| `resolve_token` | 解析元数据令牌(十六进制,例如 `0x02000001`)到其定义 | `assemblyPath`, `tokenHex` |
| `list_pinvokes` | 列出程序集中所有的 P/Invoke(DllImport)声明 | `assemblyPath` |
| `find_attributes` | 查找所有使用特定属性装饰的类型和方法 | `assemblyPath`, `attributeName` |
| `get_methods_for_type` | 获取特定类型定义的所有方法 | `assemblyPath`, `typeName` |
| `decompile_assembly` | 将整个程序集反编译为 C# 源代码 | `assemblyPath` |
| `decompile_type` | 将特定类型反编译为 C# 源代码 | `assemblyPath`, `typeName` |
| `decompile_method` | 将特定方法反编译为 C# 源代码 | `assemblyPath`, `typeName`, `methodName` |
| `dump_il` | 为整个程序集、类型或特定方法转储 IL(CIL)反汇编 | `assemblyPath`, `typeName?`, `methodName?` |
| `inspect_type` | 检查类型结构:字段、方法、属性、接口,可选包含源代码 | `assemblyPath`, `typeName`, `includeSource?` |
| `inspect_method` | 检查特定方法:签名、参数、反编译源代码,可选包含 IL | `assemblyPath`, `typeName`, `methodName`, `includeSource?`, `includeIL?` |
| `list_types` | 列出程序集中的所有类型定义 | `assemblyPath` |
| `find_methods` | 在程序集中查找方法,可按名称模式过滤 | `assemblyPath`, `pattern?` |
| `search_strings` | 在程序集的反编译源代码中搜索字符串字面量 | `assemblyPath`, `pattern`, `useRegex?` |
| `search_members` | 按名称模式搜索类型、方法、字段和属性 | `assemblyPath`, `pattern` |
| `set_breakpoint` | 在方法的特定 IL 偏移处设置虚拟断点 | `assemblyPath`, `typeName`, `methodName`, `ilOffset` |
| `list_breakpoints` | 列出所有活动的虚拟断点 | |
| `inspect_breakpoint` | 显示断点处的 IL,推断堆栈类型并查找该方法的所有调用者 | `id` |
| `clear_breakpoints` | 移除所有虚拟断点或按 ID 移除特定断点 | `id?` |
| `detect_anti_debug` | 静态分析,检测 7 类反调试技术 | `assemblyPath` |
| `detect_anti_tamper` | 静态分析,检测混淆和反篡改保护 | `assemblyPath` |
| `get_protection_report` | 将反调试和反篡改分析汇总为报告,包含风险评分(0-10)和绕过建议 | `assemblyPath` |
## 保护分析
`detect_anti_debug`、`detect_anti_tamper` 和 `get_protection_report` 仅执行静态分析。目标程序集永远不会作为 .NET 类型加载、永远不会 JIT 编译、也永远不会执行。分析仅使用 ICSharpCode.Decompiler 的类型系统和 PE 读取器。
### 反调试检测类别
- 指向已知反调试 API 的 P/Invoke 声明(IsDebuggerPresent、NtQueryInformationProcess 等)
- 托管 API 使用(System.Diagnostics.Debugger.IsAttached 等)
- 基于时间的检查(Stopwatch、GetTickCount、QueryPerformanceCounter 模式)
- 线程隐藏(NtSetInformationThread 配合 ThreadHideFromDebugger)
- TLS 回调存在(在 Main 入口点之前执行)
- 硬件断点检测(CONTEXT Dr0-Dr3 读取)
- 基于异常的 anti-debug 模式
### 反篡改检测类别
- 混淆器指纹识别(ConfuserEx、Dotfuscator、Eazfuscator、.NET Reactor、SmartAssembly、KoiVM 等以及 10+ 其他)
- 名称混淆启发式(控制字符、零宽字符、饱和度)
- 字符串加密桩(cctor 数组初始化模式、int-to-string 解密方法签名)
- 控制流混淆(switch 代理、高跳转密度)
- 完整性检查(自哈希、File.ReadAllBytes 读取自身程序集、哈希比较后终止)
- 虚拟机/虚拟化(大型 switch 分发器、加密的 IL 桩)
- 打包(PE 段名称:UPX、MPRESS、.vmp0、Themida 等)
### 风险评分
`get_protection_report` 计算风险评分(0-10):
- 高严重性/置信度发现:+1.5 分
- 中等:+0.75 分
- 低:+0.25 分
- 上限为 10
## 项目结构
```
src/DnSpyMcp/
├── Program.cs
├── Core/
│ ├── AssemblyCache.cs Thread-safe decompiler cache (keyed by path + mtime)
│ └── BreakpointRegistry.cs In-memory virtual breakpoint store
├── Models/
│ └── Results.cs All result record types
└── Tools/
├── Analysis/
│ ├── AnalysisTools.cs PE info, resources, token resolution, P/Invokes, attributes
│ ├── BreakpointTools.cs Virtual breakpoints: set, list, inspect, clear
│ ├── DecompileTools.cs C# decompilation, IL disassembly
│ ├── InspectTools.cs Type and method inspection
│ └── SearchTools.cs Type/method/member/string search
└── Security/
├── AntiDebugTools.cs Anti-debug pattern detection
├── AntiTamperTools.cs Obfuscation and anti-tamper detection
└── ProtectionReportTools.cs Aggregated protection report
```
## 已知问题
## 致谢
### Detect It Easy (DIE)
`Tools/Security/` 中的保护检测逻辑直接借鉴了 [Detect It Easy](https://github.com/horsicq/Detect-It-Easy)(作者 horsicq)使用的检测方法。
DIE 的核心洞见——保护器指纹识别应在原始二进制字节模式、PE 段元数据和元数据字符串堆搜索上运行,而非反编译源代码——是该项目中亚毫秒级检测性能的基础。多种混淆器签名(ConfuserEx、Dotfuscator、Eazfuscator、.NET Reactor、VMProtect、Dotfuscator、MPRESS、Themida 等)均改编自 DIE 的 PE 签名脚本,位于 `db/PE/`。DIE 由 horsicq 维护并贡献,采用 MIT 许可证。
### 反调试研究
反调试检测类别和 API 覆盖范围参考了以下资料:
- bengabay1994,《Anti-Debugging with .NET in Windows Environment》—— PEB字段检查(BeingDebugged、NtGlobalFlag、堆标志/ForceFlags)、StartupInfo.lpDesktop、NtCreateThreadEx 线程隐藏
- hsheric0210,《AntiDebug.NET》—— 涵盖动态 IAT 解析、手动模块映射和钩子绕过模式的 .NET 反调试与反虚拟机技术综合参考
- Check Point Research,《Anti-Debug Tricks》—— 通过 AntiDebug.NET 引用的反调试技巧
对高度混淆的程序集进行名称混淆启发式分析可能会产生误报
名称混淆检测器会标记使用单字母名称或编译器生成名称(包含 `<` `>`)的成员。标准 .NET 编译器生成的类型(lambda 闭包、异步状态机)也会计入混淆名称比率。阈值设为 30% 以减少噪音,但大量使用泛型或 LINQ 的程序集仍可能触发该检测。字符串加密检测依赖于混淆的方法名称
字符串解密方法检测器仅在方法名称本身被混淆时触发(包含控制字符或为单字母)。如果保护者使用可读的方法名称作为其字符串解密例程,则此检查无法检测到它们。cctor 数组初始化模式不受影响。程序集解析器在缺少依赖的程序集上可能出错
ICSharpCode.Decompiler 会尝试从目标程序集所在目录解析引用的程序集。如果依赖项缺失,受影响方法的反编译将回退到部分输出或跳过。PE 级操作(`get_pe_info`、`get_resources`、`resolve_token`、`list_pinvokes`)不受影响。`ThrowOnAssemblyResolveErrors` 默认设置为 false 以抑制解析器错误。P/Invoke 入口点检测仅限于 DllImportAttribute
`list_pinvokes` 和反调试 P/Invoke 扫描器仅检测使用 `[DllImport]` 装饰的方法。使用 `NativeLibrary.Load` + `GetExport`、通过 `Marshal` 的 `GetProcAddress` 或手动构建的委托函数指针等动态 P/Invoke 模式将无法被检测到。标签:CLI, dnSpy, ICSharpCode.Decompiler, IL, MCP, Model Context Protocol, .NET 8, PE/COFF, P/Invoke, SEO:MCP服务器, SEO:.NET工具, SEO:反编译工具, SEO:程序集分析, URL提取, WiFi技术, 云安全监控, 保护分析, 元数据, 反编译, 属性反射, 无头, 程序集分析, 资源查看, 静态分析