Agile.NET可以对.NET程序中的EXE、DLL分别配置代码加密、符号重命名、控制流混淆和代码虚拟化。处理“Agile.NET怎么保护指定程序集,Agile.NET程序集保护后依赖加载失败如何处理”时,需要区分【加入项目】和【实际启用保护】两个动作。即使某个依赖DLL不需要混淆,也建议把它加入同一项目,使Agile.NET能够识别程序集关系并复制到输出目录;真正需要强化保护的程序集,再单独启用对应保护方式。
一、Agile.NET怎么保护指定程序集
程序集保护不适合简单把所有DLL全部开启相同强度。主程序、核心算法库和普通依赖承担的功能不同,应该先把完整依赖关系交给Agile.NET,再决定具体保护范围。
1、先把完整程序集加入项目
①启动Agile.NET并新建保护项目。
②点击【Add】加入主EXE和项目自身使用的DLL。
③第三方或无需保护的依赖,只要属于当前程序运行所需,也可以一并加入项目。
④设置独立的【Output Directory】,不要直接覆盖原始构建目录。
⑤保存项目文件,方便后续版本继续使用同一套配置。
官方建议将组成软件的程序集都加入项目,即使其中部分程序集不准备保护,Agile.NET仍可在构建时把它们复制到输出目录。这样更容易保持保护前后的部署结构一致。
2、只给关键程序集启用保护
①在项目中选中真正需要保护的EXE或DLL。
②普通业务代码可先开启【Obfuscation】进行符号重命名。
③涉及授权、核心算法等敏感逻辑时,再启用【Secure】代码加密。
④少量高价值方法需要进一步提高逆向难度时,再使用【Code Virtualization】。
⑤普通依赖库没有保护需求时,保持原状态即可,不必为了统一配置全部开启高强度保护。
Agile.NET提供代码加密、符号重命名、控制流混淆和代码虚拟化等不同保护方式,因此保护强度可以根据程序集实际价值分配,而不是所有模块采用相同配置。
3、存在程序集互相调用时提前处理重命名关系
①确认目标DLL是否被项目中的其他程序集直接引用。
②如果多个自研程序集都需要参与符号重命名,检查【Cross Assembly Obfuscation】设置。
③存在反射调用的类型或方法,不要直接允许其名称被重命名。
④通过重命名排除或.NET的ObfuscationAttribute保留必须按名称访问的成员。
⑤重新保护后优先测试插件加载、反射创建对象和配置驱动调用。
【Cross Assembly Obfuscation】能够同步修改程序集之间的外部引用;但通过Reflection按字符串名称访问的类型或方法,在被重命名后仍可能调用失败,因此需要明确排除。
二、Agile.NET程序集保护后依赖加载失败如何处理
保护前运行正常,保护后出现“Could not load file or assembly”、TypeLoadException或启动后直接退出时,应先判断是【文件没有输出】、【引用名称发生变化】还是【签名和运行组件不匹配】。
1、先检查输出目录中的依赖是否完整
①不要从原来的bin目录直接启动程序,应进入Agile.NET生成的保护输出目录测试。
②对照保护前目录,检查运行必须的DLL是否都存在。
③发现某个依赖没有输出时,把该程序集加入Agile.NET项目后重新Build。
④如果关闭了【Runtime Embedding】,检查Agile.NET生成的x86或x64运行时组件是否已经一起部署。
⑤确认无误后再从干净目录重新启动程序。
命令行参数【DisableRuntimeEmbedding】启用后,需要自行随程序发布相应native runtime,因此遗漏运行组件同样可能造成保护后的程序无法正常启动。
2、只有部分DLL加载失败时检查符号重命名
①先暂时关闭目标程序集的【Obfuscation】,只保留【Secure】重新生成。
②如果程序恢复正常,说明问题更可能与符号重命名有关。
③检查失败类型是否通过反射、插件发现、序列化或配置文件按名称加载。
④将必须保持名称稳定的类型或成员加入【Renaming Exclusions】。
⑤自研程序集之间存在直接引用时,再检查是否需要【Cross Assembly Obfuscation】。
这种对照方式可以把“代码加密问题”和“名称变化问题”快速分开。Agile.NET官方也明确指出,Reflection API是符号重命名后较容易出现兼容问题的场景。
3、强名称程序集检查重新签名
①确认原程序集是否使用Strong Name签名。
②在Agile.NET项目中指定原项目使用的同一密钥文件。
③重新构建保护程序集。
④清空旧输出目录,避免保护前后的不同版本DLL混用。
⑤重新检查引用程序集版本和Public Key Token是否一致。
Agile.NET在修改受保护程序集后可以使用指定密钥重新签名。强名称程序集如果没有正确重新签名,其他组件按原身份加载时就可能出现引用失败。
4、使用程序集合并时检查主从关系
①进入【Merging】检查是否启用了程序集合并。
②确认【Primary Assembly】选择的是实际程序入口。
③核对被合并DLL是否确实适合成为Secondary Assembly。
④排查阶段可暂时关闭合并,再测试普通DLL部署方式。
⑤普通模式恢复后,再重新加入合并功能验证。
Agile.NET会在其他保护操作之前执行Assembly Merging,而且Secondary Assembly原先配置的保护设置会被忽略,最终使用Primary Assembly的保护设置。因此合并配置本身也会改变程序集的组织方式。
三、依赖问题解决后怎么重新建立稳定的保护配置
依赖恢复后,不适合马上把之前关闭的功能全部重新打开。更可靠的方式是建立一套能够启动和完成核心业务的基础保护方案,再逐层增加保护强度。
1、逐层恢复保护功能
①先保留目标程序集和完整依赖,只开启【Secure】或基础保护。
②确认启动、程序集加载和核心功能正常。
③再增加【Obfuscation】,重点验证反射和插件场景。
④随后按需要加入【Control Flow Obfuscation】或【Code Virtualization】。
⑤每增加一层就运行同一组回归测试,并记录是哪一项开始引起异常。
这样可以直接定位保护机制与程序结构的兼容边界,而不是在一套复杂配置中反复猜测。
2、把保护后的输出作为独立发布物验证
①清空测试目录,只复制Agile.NET最终输出内容。
②在没有开发环境依赖的机器上启动程序。
③测试主程序、插件、资源文件和各业务DLL的加载。
④发生混淆后异常时,保留同一次构建产生的Obfuscation Map。
⑤利用Map解码保护后的调用栈,再定位到原始类型和方法。
Agile.NET在启用符号重命名时可以生成映射文件,用于把混淆后的异常调用栈还原成原始代码名称,这对定位保护版本中的加载异常尤其重要。
总结
Agile.NET保护指定程序集时,保护范围和依赖范围不应混为一谈:核心EXE或DLL可以单独采用更强的代码加密、混淆或虚拟化,但运行所需程序集仍应完整纳入项目和最终发布目录。保护后出现依赖加载失败时,先确认输出文件和运行组件,再检查符号重命名、跨程序集引用、反射调用和强名称签名,通常能够较快缩小问题范围。随后用分层恢复保护的方式重新建立稳定基线,可以避免为了修复一个依赖问题而整体降低保护强度。如需进一步了解Agile.NET指定程序集保护、程序集依赖加载及保护后运行异常排查方法,欢迎联系咨询。