优先选SharpObfuscator:支持.NET 5~8、更新勤、CI友好;ConfuserEx已停更且对新特性支持差;Dotfuscator商业版稳但贵,免费版功能受限且易出错。

混淆器选哪个:Dotfuscator、ConfuserEx、SharpObfuscator 怎么挑
没有银弹,选错工具反而让代码更易被破。Dotfuscator 商业版最稳但贵,免费版功能阉割严重;ConfuserEx 开源免费,但 2022 年后停止维护,对 .NET 6+ 的泛型和 Source Generator 支持差,容易混淆失败甚至生成无效 IL;SharpObfuscator 更新勤、支持 .NET 5/6/7/8,命令行友好,适合 CI 集成。
实操建议:
- 新项目优先用
SharpObfuscator,配置文件简洁,sharpreo.exe --project obf.xml一行就能跑 - 若必须用 ConfuserEx,避开
AntiILDasm和InvalidMetadata这两个保护项——它们在 .NET Core+ 下常导致System.BadImageFormatException - Dotfuscator 免费版禁用
String Encryption,否则会把资源字符串混淆成空,运行时报NullReferenceException在ResourceManager.GetObject
哪些代码不能乱混淆:public API、反射调用、序列化类怎么保
混淆器不认语义,只认符号名。它把 JsonSerializer.Deserialize<User> 里的 User 类字段名一改,JSON 就绑定不上;把 Assembly.GetExecutingAssembly().GetType("PluginLoader") 里的字符串字面量一换,插件就加载失败。
实操建议:
- 所有被
JsonSerializer、XmlSerializer、Newtonsoft.Json反序列化的类,加[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]不够,还得加[Obfuscation(Exclude = true)] - 用到反射的类型名、方法名、属性名,统一放进混淆配置的
<exclude>块,别依赖“保留 public 成员”这种默认策略 - WPF 的
x:Name、ASP.NET Core 的[FromRoute("id")]、EF Core 的[Column("user_name")]——这些字符串硬编码点,必须人工核对是否被混淆器误动
混淆后为什么程序启动就崩溃:常见 IL 损坏和元数据异常
不是混淆没生效,而是混淆器改了 IL 却没同步修正元数据校验和,或者跳过了某些 try/catch 块内的异常处理逻辑,导致 JIT 编译失败或运行时报 InvalidProgramException。
实操建议:
- 混淆后立刻用
ildasm打开输出 DLL,执行File → Dump → With IL Assembly,搜.method看有没有非法指令(如call后跟了不存在的方法 token) - 用
peverify /verbose YourApp.dll检查元数据一致性,报error : [MD]: Error in method就说明混淆破坏了方法签名 - 关闭混淆器的
Control Flow Obfuscation——它在 async 方法里极易出问题,.NET 6+ 的ValueTask状态机一混淆就崩
混淆只是拖延时间:真正该防的是调试器附加和内存 dump
混淆防不了有经验的人。他们用 dnSpy 直接 Attach 进程,下断点看堆栈,或者用 procdump -ma 抓内存镜像,再用 dotnet-dump analyze 提取明文字符串。这时候混淆过的变量名毫无意义。
实操建议:
- 加基础反调试:在
Main()开头调用Debugger.IsAttached,配合CheckRemoteDebuggerPresentP/Invoke,检测到直接Environment.Exit(1) - 敏感字符串别写死:用 XOR 加密 + 运行时解密,密钥藏在环境变量或注册表非标准路径(如
HKEY_CURRENT_USER\Software\TempKey),别放appsettings.json - 关键逻辑扔进 native DLL(哪怕只封装一个函数),C# 层只传参调用——.NET 反编译再强,也看不到 x64 汇编里怎么算的
混淆不是终点,是起点。真正难搞的从来不是名字变了,而是你忘了 Assembly.LoadFrom 加载的 DLL 没一起混淆,或者日志里还留着未加密的 API 密钥。










