1.问题
用.NET Reactor混淆dll后导致Revit插件不能正常加载,好吧,问题发生了,那就先分析下吧;
用相同的混淆设置,Revit2020的插件可以加载,那么初步判断是混淆设置的原因,
继续验证猜想~
不混淆dll,发现Revit2021可以正常加载dll,看来是混淆设置的问题,而且这个问题在Revit2021中是存在的,那么怎么解决?
2.解决过程
此过程记录博主分析解决该问题的过程,会涉及到一些知识点,如果读者时间有限,可以跳到解决方案一章尝试,如果问题还不能解决,则可参考该过程或其他文章;
2.1.调试
附加到进程,开始调试,注意是在Revit2021加载插件之前进行附加调试,出现以下异常,
好吧,问题已经比较清晰了,是执行createRibbonPanel过程中发生了"The specified tab cannot be found!"的异常,原因是混淆dll后导致了创建tab的过程出现了异常或者find tab的参数值有问题,那么该怎么办?原因是混淆导致入口类有问题,
那么很简单,排除入口类的混淆即可,是这样吗?
2.2.排除入口类的混淆
ObfuscationAttribute 类
// Exclude this type from obfuscation, but do not apply that
// exclusion to members. The default value of the Exclude
// property is true, so it is not necessary to specify
// Exclude=true, although spelling it out makes your intent
// clearer.
[ObfuscationAttribute(Exclude=true, ApplyToMembers=false)]
public class Type2
{
// The exclusion of the type is not applied to its members,
// however in order to mark the member with the "default"
// feature it is necessary to specify Exclude=false,
// because the default value of Exclude is true. The tool
// should not strip this attribute after obfuscation.
[ObfuscationAttribute(Exclude=false, Feature="default",
StripAfterObfuscation=false)]
public void MethodA() {}
// This member is marked for obfuscation, because the
// exclusion of the type is not applied to its members.
public void MethodB() {}
}
当然,这里我用的是[ObfuscationAttribute(Exclude=true, ApplyToMembers=true)],避免对类及其成员进行混淆,发现这样设置后还是加载出异常,即使对所有可能会发射加载的类进行这样的设置,还是一样的问题,
是.NET Reactor没有遵循上述规则吗?事实是遵循了(读者可自行进行测试对比,分别用IL Spy反编译对比设置和没设置该特性的类的内容),实际是因为其他混淆设置导致了该问题,因为像.NET Reactor这类的专业混淆工具混淆设置很强大,除了常规的混淆外,还有进一步的处理(如果你勾选了的话);
2.3.使用.NET Reactor自带的排除混淆设置
经实际测试,插件依然不能正常加载...
2.4.排除选项
因为问题已经很清晰,且排除混淆后问题依然存在,那么很可能是除了这些常规的混淆之外,.NET Reactor还做了其它进一步的处理(因为勾选了那些选项);
经测试是由于开启了Anti ILDASM选项,鼠标悬浮到该项上方时,左边详细说明是:使用反编译工具来抑制反编译,更多关于该选项的说明 谈anti ILdasm的原理以及anit 框架API的可行性
取消该选项,问题解决。
或者保留Anti ILDASM选项,将Inject Invalid Metadata子项设置为false,问题同样解决。
3.结论
Revit2021加载插件dll方式和之前的版本有所不同,其依赖metadata去读取dll的信息;对应的混淆工具要将Anti ILDASM选项的Inject Invalid Metadata子项设置为false;
混淆工具很强大,根据需要使用提供的设置,即在反混淆和兼容性之间做一个平衡;