2026年.NET Framework项目代码保护:ConfuserEx 2.0核心机制与实战配置指南

📅 2026/8/12 9:41:03
2026年.NET Framework项目代码保护:ConfuserEx 2.0核心机制与实战配置指南
1. 项目缘起为什么在2022年还要用ConfuserEx 2.0如果你是一个.NET开发者尤其是那些开发桌面客户端、游戏插件或者需要分发核心算法库的朋友代码保护这个话题你一定不陌生。在.NET生态里代码混淆器就像给源代码穿上了一件“迷彩服”让逆向工程变得困难。今天要聊的ConfuserEx虽然它的最后一个稳定版本2.0发布于2016年但直到今天在特定的场景下它依然是一个绕不开的经典工具。你可能会问都2026年了.NET Core/5/6/7/8都这么成熟了还有必要折腾一个十年前的混淆器吗答案是在某些情况下非常有必要。首先.NET Framework的存量项目依然庞大。很多企业级应用、工业控制软件、或者一些依赖特定COM组件的老系统依然运行在.NET Framework 4.x上。对于这些项目迁移到.NET Core/5的成本可能非常高甚至不现实。ConfuserEx 2.0对.NET Framework 4.0到4.8的支持非常成熟稳定这是它至今仍有生命力的根本原因。其次ConfuserEx的混淆强度在同类工具中依然可圈可点。它提供了名称混淆、控制流混淆、字符串加密、资源加密、防调试、防篡改等多种保护手段。特别是它的控制流混淆能将简单的if-else、for循环变成复杂的switch-gotospaghetti代码极大地增加了静态分析的难度。对于防止简单的反编译和代码窃取这套组合拳依然有效。再者ConfuserEx是开源的。这意味着你可以完全掌控它的行为甚至可以根据自己的需求进行定制化修改。这对于有特殊保护需求或者对安全有极致要求的团队来说是一个巨大的优势。相比之下很多商业混淆器是闭源的“黑盒”你无法确切知道它在你的程序集里做了什么。当然我们也要正视它的局限性。它对.NET Core/5的原生支持几乎为零虽然通过一些“魔改”可以让它处理.NET Standard库但过程繁琐且不稳定。它的配置方式基于XML对于新手来说学习曲线稍陡。而且由于年久失修社区活跃度低遇到一些新框架下的兼容性问题比如WPF的XAML绑定、反射调用等时可能需要自己花时间去踩坑和解决。所以这篇文章的目标读者很明确那些仍在维护或开发.NET Framework项目需要对程序集进行基础到中级强度保护且愿意花时间理解工具原理和配置的开发者。如果你正在寻找一个“一键无敌”的终极保护方案或者你的项目已经完全迁移到了.NET 6那么这篇文章可能不是你的菜。但如果你手头正好有这样一个“老项目”并且被代码泄露的问题所困扰那么跟着我一起重新审视一下这款经典工具或许能给你带来意想不到的收获。2. ConfuserEx 2.0 核心保护机制深度拆解在动手配置之前我们必须先搞清楚ConfuserEx到底能做什么以及它是怎么做的。知其然更要知其所以然这样才能在后续的配置中做出正确的选择避免“一顿操作猛如虎一看效果原地杵”的尴尬。2.1 名称混淆最基础也最容易出问题名称混淆是几乎所有混淆器的标配ConfuserEx也不例外。它的原理很简单将程序集中的类名、方法名、字段名、属性名、参数名等标识符替换成毫无意义的字符比如a,b,c1,d2或者不可见的Unicode字符。为什么需要它想象一下你反编译一个程序集看到的全是CustomerRepository、CalculateTotalPrice、_connectionString这样清晰的名字业务逻辑一目了然。但如果它们变成了a、b、c理解成本就大大增加了。这对于防止竞争对手快速理解你的代码结构非常有效。ConfuserEx的实现细节ConfuserEx的名称混淆策略是可配置的。你可以在配置文件中指定哪些模块、哪些类型、哪些成员需要被混淆。它支持多种重命名规则字母序列 按顺序使用a, b, c... aa, ab...不可打印字符 使用在IDE中无法正常显示或输入的Unicode字符这会让反编译工具显示乱码。数字序列 使用数字作为名称。增强字母序列 在字母序列基础上增加随机性。重要提示名称混淆是破坏性最强的操作之一极易引发运行时异常。特别是以下场景必须排除混淆公开的APIPublic类型和成员 如果你的DLL要被其他程序引用那么公开的接口名称必须保持稳定否则调用方会找不到方法。序列化/反序列化涉及的类 例如使用XmlSerializer、Json.NET默认使用属性名或BinaryFormatter时类名和属性名是序列化数据的一部分混淆后会导致无法反序列化。反射调用的成员 如果代码中使用了Type.GetMethod(MethodName)或propertyInfo.GetValue(obj)并且通过字符串硬编码了成员名称那么这些名称不能被混淆。WPF/XAML数据绑定 XAML中的Binding PathPropertyName依赖于属性名称混淆会导致绑定失效。COM互操作和P/Invoke 这些接口的名称必须与外部约定保持一致。在ConfuserEx的配置中你需要非常小心地使用rule标签和pattern来排除这些不应被混淆的项。一个常见的做法是先排除所有presetnone然后只对明确知道安全的内部私有成员应用混淆规则。2.2 控制流混淆让代码逻辑“面目全非”如果说名称混淆是给代码“改名换姓”那么控制流混淆就是给代码“整容”而且是那种连亲妈都认不出来的整容。这是ConfuserEx的杀手锏也是混淆强度的核心体现。它的工作原理是什么控制流混淆会改变方法内部IL代码的执行流程结构但不改变其最终执行结果。它通常通过以下手段实现插入不透明谓词 添加一些永远为true或永远为false的判断条件但编译器无法优化掉它们从而增加无用的分支。将顺序结构改为跳转结构 把简单的if-else改成switch加goto的混乱组合。平铺控制流 将嵌套的、层次清晰的控制流如循环嵌套条件判断打散成一个扁平的、由goto语句连接的状态机。实际效果对比混淆前一个简单的判断方法public string GetGrade(int score) { if (score 90) return A; else if (score 60) return B; else return C; }经过控制流混淆后其对应的IL代码可能被转换成类似这样的逻辑用伪代码表示public string GetGrade(int score) { int num score; switch (num * 7 % 3) { // 不透明谓词结果总是0,1,2中的一个但反编译工具难以分析 default: goto IL_001a; case 0: goto IL_002b; case 1: goto IL_003c; } IL_001a: if (num 90) { goto IL_004d; } goto IL_005e; IL_002b: if (num 60) { goto IL_006f; } goto IL_0080; IL_003c: // ... 更多的goto和标签 IL_004d: return A; IL_005e: // ... 更多的跳转 }在反编译工具如dnSpy中查看时代码会变成一堆难以阅读的goto和标签逻辑支离破碎极大地阻碍了人工分析。配置要点控制流混淆强度通常可调。在ConfuserEx中它作为一个保护插件ctrl flow存在。高强度混淆会让代码更难以分析但也可能轻微影响运行性能通常可忽略不计并增加程序集大小。对于性能极度敏感的算法核心可能需要测试后决定是否启用或调整强度。2.3 字符串加密与资源加密藏起明文信息代码逻辑被混淆了但代码里的字符串常量还是明晃晃的在那里比如数据库连接字符串、API密钥、敏感提示信息、版权声明等。字符串加密就是为了解决这个问题。ConfuserEx的字符串加密 它会将程序集中所有的字符串常量ldstr指令加载的字符串加密存储并在运行时首次使用时动态解密。这样用反编译工具直接查看IL或反编译代码时看到的是一串乱码或者一个解密方法的调用。资源加密 对于嵌入到程序集中的资源文件如图片、配置文件、XML等ConfuserEx也可以将其加密防止被直接提取。注意事项性能影响 每个加密的字符串在第一次访问时都需要解密会带来一次性的、微小的运行时开销。对于大量字符串常量这个开销是累积的。反射和序列化 同样如果字符串会被用于反射查找如Type.GetType(Namespace.ClassName)或作为序列化的键加密会导致运行时错误。需要在配置中排除这些特定的字符串或包含它们的类型。调试体验 在调试时查看变量看到的可能是解密前的乱码会影响调试效率。建议在开发调试版本时关闭此功能。2.4 其他辅助保护措施除了上述三大核心ConfuserEx还集成了许多实用的保护插件防调试/防篡改 检测程序是否被调试器附加或者程序集文件是否被修改。如果检测到可以触发自定义行为如退出、抛出异常。常量加密 不仅加密字符串还可以加密数字、布尔值等常量。引用代理 将对方法、字段的直接调用替换为通过委托或反射的间接调用增加分析难度。无效元数据注入 向程序集中添加无用的类型、方法、字段等元数据干扰反编译工具。压缩 压缩程序集的内容减小文件体积同时增加直接查看的难度。这些功能可以根据需要组合使用形成一个多层次、立体化的保护网。但切记保护强度与兼容性、性能通常是 trade-off 的关系。配置越高潜在的运行时问题可能越多。3. 实战配置从零开始构建你的混淆方案理论说了一大堆现在我们来点实际的。假设我们有一个名为MyBusinessApp.exe的.NET Framework 4.7.2控制台应用程序它引用了几个自己编写的核心业务逻辑库CoreLogic.dll。我们的目标是保护CoreLogic.dll同时确保主程序MyBusinessApp.exe能正常运行。3.1 环境准备与工具获取首先你需要ConfuserEx。虽然原项目在GitHub上已经归档但二进制文件依然可以找到。最可靠的方式是从其GitHub发布页面下载https://github.com/yck1509/ConfuserEx/releases。找到最新的2.0版本例如ConfuserEx v2.0.0.zip并下载。解压后你会看到如下目录结构ConfuserEx/ ├── Confuser.CLI.exe # 命令行工具用于集成到CI/CD ├── ConfuserEx.exe # 图形化界面工具推荐新手使用 ├── ConfuserEx.dll # 核心库 ├── Confuser.Core.dll # 核心库 ├── Confuser.Protections.dll # 保护插件库 ├── Confuser.Renamer.dll # 重命名插件库 └── plugins/ # 可放置第三方插件对于初学者我强烈建议从图形化界面ConfuserEx.exe开始。它提供了可视化的项目配置、实时错误检查和一键混淆功能。3.2 创建并剖析ConfuserEx项目文件.crprojConfuserEx的配置保存在一个XML格式的项目文件.crproj中。我们可以用GUI创建但理解其结构对于排错和高级配置至关重要。一个最基础的、能工作的项目文件如下所示?xml version1.0 encodingutf-8? project outputDir混淆后输出 baseDir. xmlnshttp://confuser.codeplex.com rule patterntrue presetnone inheritfalse !-- 规则会在这里细化 -- /rule module pathMyBusinessApp.exe !-- 对主程序模块的配置 -- /module module pathCoreLogic.dll !-- 对核心逻辑库的配置 -- /module probe path./ !-- 告诉ConfuserEx在哪里查找依赖项 -- /project让我们分解关键部分project根元素 定义了输出目录outputDir和基础目录baseDir。baseDir通常是项目文件所在目录outputDir是相对baseDir的路径。rule元素 这是配置的核心。它定义了保护规则如何应用到程序集上。patterntrue表示这个规则默认应用于所有模块。presetnone是最保守的设置表示默认不应用任何保护。inheritfalse表示子模块不继承此规则通常保持false即可。我们会在rule内部通过protection和exclude属性来精细控制。module元素 每个需要被处理的程序集.exe或.dll都需要一个module条目。path是相对于baseDir或probe路径的程序集文件名。probe元素 指定ConfuserEx在解析程序集引用时搜索的目录。通常设置为.当前目录或libs等依赖库目录。3.3 为CoreLogic.dll配置强混淆规则我们的保护重点是CoreLogic.dll。假设这个库的所有公共API都只在内部使用即只有MyBusinessApp.exe会引用它我们可以对它应用较强的混淆。首先在rule patterntrue presetnone内部我们添加一个更具体的规则来针对CoreLogic.dllrule patterntrue presetnone inheritfalse !-- 首先默认规则什么都不做安全第一 -- !-- 然后为CoreLogic.dll创建一个强混淆规则 -- rule patternCoreLogic.dll presetmaximum inheritfalse !-- “maximum”预设会启用几乎所有保护但我们可以微调 -- protection idrename actionremove / !-- 我们先禁用重命名后面单独配 -- protection idconstants actionremove / !-- 常量加密有时会引发问题先禁用 -- /rule /rule这里我们用了presetmaximum但立刻移除了rename和constants保护。这是因为我们想对重命名进行更精细的控制。现在让我们为CoreLogic.dll单独配置重命名规则rule patternCoreLogic.dll presetmaximum inheritfalse !-- 启用控制流、字符串加密、防调试等 -- !-- 单独配置重命名 -- protection idrename argument namemode valuesequential / !-- 使用顺序字母模式 -- argument namerenEnum valuetrue / !-- 重命名枚举成员 -- argument namerenArgs valuetrue / !-- 重命名方法参数 -- /protection !-- 排除不应该重命名的项 -- rule patternnamespace(MyCompany.CoreLogic.Models.*) inheritfalse protection idrename actionremove / /rule /rule在上面的配置中我们为rename保护指定了模式(sequential)和选项。我们添加了一个子规则使用通配符namespace(MyCompany.CoreLogic.Models.*)匹配Models命名空间下的所有类型并移除了rename保护。这是因为Models命名空间下的类很可能是DTO数据传输对象会被序列化/反序列化必须保持名称稳定。3.4 处理MyBusinessApp.exe的敏感点主程序MyBusinessApp.exe通常不需要强混淆因为它是对外分发的入口。过度混淆可能导致杀毒软件误报、系统兼容性问题。但其中可能包含一些需要保护的逻辑比如许可证检查、加密算法等。我们可以为它创建一个温和的规则rule patternMyBusinessApp.exe inheritfalse !-- 只启用基础保护 -- protection idctrl flow / !-- 控制流混淆 -- protection idanti debug / !-- 防调试 -- protection idanti tamper / !-- 防篡改 -- !-- 排除主入口点和涉及UI/反射的类 -- rule patternname(Program.Main) inheritfalse protection idctrl flow actionremove / /rule rule patterntype(MyCompany.MyBusinessApp.ViewModels.*) inheritfalse protection idctrl flow actionremove / protection idrename actionremove / /rule /rule这里的关键是使用pattern精确排除name(Program.Main) 排除主入口方法确保程序能正常启动。type(MyCompany.MyBusinessApp.ViewModels.*) 排除所有ViewModel类型。如果这是一个WPF应用ViewModel的属性通常用于数据绑定混淆会导致UI绑定失败。3.5 在GUI中完成配置与首次运行将上述XML配置整合到一个完整的.crproj文件中后我们可以用GUI打开它。打开ConfuserEx.exe。点击Project-Open...选择你的.crproj文件。左侧面板会列出所有模块和规则。你可以在这里进行可视化编辑比如右键点击模块添加/移除保护双击规则修改模式。关键一步点击Settings选项卡。确保Debug选项是未勾选状态。Debug模式会生成一个映射文件.map用于将混淆后的名称映射回原名这仅用于调试混淆器本身发布版本绝对不能勾选点击右下角的Protect!按钮。如果配置正确ConfuserEx会开始处理程序集并在下方的输出窗口显示进度和结果。最终混淆后的程序集会生成在outputDir指定的目录中。4. 混淆后的验证与深度排错指南点击Protect!没有报错只是万里长征第一步。混淆后的程序集能否正常工作才是真正的考验。这一步往往是最容易踩坑的地方。4.1 基础功能测试你的程序还“认识”自己吗首先进行最基础的黑盒测试直接运行 将混淆后的MyBusinessApp.exe和CoreLogic.dll以及所有其他依赖项复制到一个干净的目录尝试运行主程序。观察是否能正常启动执行核心业务流程。单元测试如果存在 运行针对核心逻辑的单元测试。这是检验混淆是否破坏内部逻辑的绝佳方式。注意测试项目需要引用混淆后的DLL。集成测试 如果有端到端的测试场景也跑一遍。如果程序直接崩溃、功能异常或测试大面积失败那么混淆很可能破坏了某些关键部分。4.2 常见崩溃原因与排查路径当混淆后的程序出现问题时不要慌张按以下路径系统性排查问题一MissingMethodException,TypeLoadException或FileLoadException症状 程序启动时或调用某个功能时立即抛出此类异常。根因分析 这几乎总是因为名称混淆误伤了不该混淆的成员。特别是序列化 被[Serializable]标记的类或其属性/字段被混淆。反射调用 代码中使用了Invoke、GetMethod、GetProperty等并且方法/属性名是字符串字面量。接口实现/虚方法重写 混淆了接口方法或重写方法的名称导致运行时找不到匹配项。P/Invoke 或 COM Interop 混淆了DllImport的方法名或COM接口的方法名。排查工具使用映射文件谨慎 在开发阶段可以临时在ConfuserEx的Settings中勾选Debug生成一个.map文件。这个文件记录了混淆前后的名称对应关系。当异常发生时查看异常信息中的类型名和方法名然后在.map文件中搜索看它是否被意外混淆了。切记发布版本绝不能带.map文件代码审查 仔细检查你的代码库搜索所有使用反射、特性如[JsonProperty(Name ...)]、序列化、动态调用的地方。解决方案 在ConfuserEx配置中为涉及到的特定类型、方法或包含它们的命名空间添加排除规则。例如rule patterntype(MyCompany.CoreLogic.Serializers.*) inheritfalse protection idrename actionremove / /rule rule patternmember(MyCompany.CoreLogic.Service.*.Invoke*) inheritfalse protection idrename actionremove / /rule问题二WPF/Windows Forms界面绑定失效控件显示空白或抛出XAML解析错误症状 UI界面显示不正常数据不显示或者设计时能运行但混淆后出错。根因分析WPF数据绑定Binding PathPropertyName或{Binding PropertyName}依赖于属性名称。属性名被混淆后绑定引擎找不到属性。XAML中的x:Name 如果后台代码通过FindName或字段访问x:Name指定的元素该名称不能被混淆。资源字典 通过StaticResource引用的资源键名不能被混淆。解决方案排除所有ViewModel、Model、Converter等用于绑定的类型及其公共属性。对于x:Name通常对应后台的字段需要排除整个View页面/窗口的类。!-- 排除所有View和ViewModel -- rule patternnamespace(MyCompany.MyBusinessApp.Views.*) inheritfalse protection idrename actionremove / protection idctrl flow actionremove / !-- 控制流混淆也可能影响初始化逻辑 -- /rule rule patternnamespace(MyCompany.MyBusinessApp.ViewModels.*) inheritfalse protection idrename actionremove / /rule问题三程序集强签名验证失败症状 如果原始程序集是强命名的混淆后运行时可能提示“强名称验证失败”或程序集无法加载。根因分析 混淆过程修改了IL代码破坏了基于原始内容的强名称签名。解决方案 ConfuserEx支持在混淆后重新签名。你需要在Settings中找到Strong Name选项。勾选Key File并选择你的.snk或.pfx签名文件。如果密钥文件有密码填写密码。ConfuserEx会在保护流程的最后对修改后的程序集重新进行强名称签名。问题四性能显著下降或内存异常症状 程序运行变慢或在某些操作时内存激增。根因分析字符串加密 如果程序中存在海量字符串常量且每个都在首次访问时解密可能会在启动时造成可感知的延迟。控制流混淆 过于复杂的控制流会增加CPU的分支预测失败率在极端情况下可能影响性能。资源加密 大型资源文件在解密时可能占用较多内存和时间。解决方案性能剖析 使用性能分析工具如Visual Studio Profiler、dotTrace对比混淆前后的程序定位热点。针对性禁用 对于性能关键路径上的方法或类在规则中排除控制流混淆和字符串加密。分级保护 对核心算法库应用强混淆对UI层、IO层等应用弱混淆或无混淆。4.3 混淆效果验证它真的有用吗测试通过后我们还需要验证混淆是否真的起到了保护作用。使用反编译工具查看 用dnSpy、ILSpy或dotPeek等工具打开混淆后的CoreLogic.dll。你应该看到类名、方法名变成了a, b, c等无意义字符。方法内部的代码逻辑充斥着goto和令人费解的开关语句如果启用了控制流混淆。字符串常量显示为对解密方法的调用或乱码。尝试理解业务逻辑 找一个你熟悉的、简单的业务方法尝试通过反编译的代码去理解它。如果花费了远超预期的时间甚至无法理清逻辑说明混淆是有效的。检查元数据 反编译工具是否成功解析了所有类型是否有错误提示一些高级混淆可能会注入无效元数据导致反编译工具部分功能失效。记住没有绝对无法破解的混淆。ConfuserEx的目标是提高逆向工程的门槛和成本让大多数潜在的攻击者知难而退而不是构建一个“铜墙铁壁”。对于极其敏感的核心算法应考虑结合代码混淆、本地原生代码C/CLI以及服务器端验证等多重保护手段。5. 进阶配置与持续集成集成当你掌握了基础配置并能成功运行后可以考虑更高级的用法让混淆流程更自动化、更健壮。5.1 使用外部注释文件进行精确排除手动编写大量的rule来排除特定类型和方法非常繁琐且容易遗漏。ConfuserEx支持通过Obfuscation特性Attribute在源代码级别进行声明式排除。这是更优雅和安全的做法。首先在你的C#项目中定义一个内部使用的特性类或者直接使用System.Reflection.ObfuscationAttribute如果可用// 如果使用的是 .NET Framework 全版本通常已经内置了 System.Reflection.ObfuscationAttribute // 只需要在需要排除的类或方法上标记即可 [System.Reflection.Obfuscation(Feature renaming, Exclude true)] public class MySerializableModel { [System.Reflection.Obfuscation(Feature renaming, Exclude true)] public string SensitiveProperty { get; set; } } // 或者排除控制流混淆 [System.Reflection.Obfuscation(Feature control flow, Exclude true)] public class PerformanceCriticalClass { public void CriticalMethod() { } }然后在ConfuserEx的配置中你不需要为这些已经标记的类型编写复杂的rule。ConfuserEx在处理时会读取这些元数据并自动排除。这极大地简化了配置并将保护策略与源代码绑定更不容易出错。5.2 集成到CI/CD流水线中对于团队项目每次手动运行GUI进行混淆是不可接受的。我们需要使用命令行工具Confuser.CLI.exe将其集成到构建流程中。假设你的项目结构如下src/ ├── MyBusinessApp/ ├── CoreLogic/ build/ confuser/ ├── Confuser.CLI.exe ├── MyProject.crproj你可以创建一个批处理脚本obfuscate.bat或PowerShell脚本放在confuser/目录下echo off REM 进入脚本所在目录 cd /d %~dp0 REM 运行Confuser.CLI指定项目文件 Confuser.CLI.exe MyProject.crproj REM 检查退出代码 if %errorlevel% neq 0 ( echo Confusion failed! exit /b %errorlevel% ) echo Confusion succeeded.然后在你的MSBuild项目文件.csproj中可以在PostBuildEvent中添加调用或者在Azure DevOps、Jenkins、GitHub Actions等CI/CD工具中添加一个构建步骤来执行这个脚本。在GitHub Actions中的示例步骤- name: Obfuscate Assemblies shell: pwsh run: | cd ./confuser ./Confuser.CLI.exe ./MyProject.crproj注意事项确保CI服务器上安装了正确版本的.NET Framework运行时ConfuserEx运行所需。混淆步骤应放在单元测试之后但在打包如生成安装程序之前。妥善管理签名密钥文件.snk/.pfx在CI环境中使用安全的秘密存储方式传递密码。5.3 处理多模块与依赖关系大型项目通常由多个程序集构成且有复杂的依赖关系。ConfuserEx能很好地处理这些情况关键在于probe路径和正确的模块顺序。probe路径 必须包含所有被混淆模块所依赖的程序集所在目录。否则ConfuserEx在分析依赖时会失败。你可以添加多个probe路径。模块顺序 在.crproj文件中module的顺序有时很重要。通常应该先列出被依赖的库如CoreLogic.dll再列出依赖它们的主程序如MyBusinessApp.exe。ConfuserEx会按照顺序处理并确保在混淆依赖项时引用它的模块能正确更新引用。循环依赖 .NET程序集应避免循环依赖。如果存在ConfuserEx可能无法正确处理。最好的办法是重构代码消除循环依赖。一个处理多模块和第三方依赖的配置片段示例project outputDir.\Obfuscated baseDir.\BuildOutput probe path.\BuildOutput / !-- 主输出目录 -- probe path.\packages\Newtonsoft.Json.13.0.1\lib\net45 / !-- 第三方库目录 -- probe path.\RefAssemblies / !-- 其他引用程序集 -- module pathMyCompany.Utilities.dll / module pathMyCompany.CoreLogic.dll / module pathMyCompany.DataAccess.dll / module pathMyBusinessApp.exe / !-- 注意通常不混淆第三方库如Newtonsoft.Json.dll所以不列在这里 -- /project通过以上这些进阶实践你可以将ConfuserEx从一个手动工具转变为一个可靠、自动化、可重复的代码保护环节无缝嵌入到你的软件交付流程中为你的.NET Framework项目提供持续、稳定的基础保护。