Dotfuscator混淆后不能运行的问题

是这样的,在开发一个软件后,想用代码混淆工具进行混淆,在试用了ConfuserEx,DotNETReactor,MaxtoCode,Dotfuscator等工具后,发现一个问题,再混淆之后,程序无法运行,会报错。如下图:

这下好了,由于考虑到并未引用其它程序集,该程序都在一个程序集下,那么估计多半是代码导致。因为混淆工具大部分功能是依靠反射,将原代码获取后重新整理,进行的是名称或是字符串混淆;而流程混淆理论上在同一个程序集下的程序,因为并不含本程序集外的流程,即便混淆改变也通常是不会导致报错的。

所以,解决之道就是:第一步找到会引发报错的代码位置,第二步混淆的时候将其排除在外就可以了。

这里有了思路,于是开始找报错位置。实际操作,其实还有一步要先操作,就是确定哪些混淆工具支持排除项,简单操作试了下,觉得Dotfuscator可以,于是就采用了这个软件,通过排除法来确定混淆出错的代码位置,使用方式参考这个链接Dotfuscator使用。这里一个个排除比较麻烦,于是想到有个大问题:反射可不可以混淆?理论上。。。应该可以的,不过,好象也听过反射混淆后不能运行的案例。由于本项目采用了反射,因此首先怀疑是反射导致。

查找所有用反射的地方,选择其中一个排除混淆,看前后混淆结果对比。起初试了几个,发现没有什么差别,都可以,再多试了几次之后,发现了有的地方不同,从而确定了反射可能会导致混淆失败的结论。

其出错代码在这句:

return Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(MethodBase.GetCurrentMethod().DeclaringType.Namespace + "." + imagePath));
于是采用最小化排除的方式,进入rename后exclude中排除含有此代码的方法来混淆

实测依然有问题,点击运行依然报错。用反编译工具查看此方法函数代码如下:

public static Image ᜀ(string A_0)
{
return Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ᜋ.b("ᴲ", 11) + A_0));
}
发现方法名已经混淆了,看来是没有排除成功。接着如下图多勾选上级的类名称,然后点击混淆,惊喜的是,这次成功运行!原因嘛应该是该方法为静态方法,调用该方法会引用类名称,所以上级的类名称也要勾选。

至此问题得以解决,查看反编译的代码,可以看到函数方法名得以排除,看来排除成功了,所以混淆后能够运行。

总结经验:经实际调试发现,反射确实可能导致混淆失败,例如上面通过反射要再次获取方法,而单纯获取程序集的信息是不会导致失败的。在混淆的时候,记得进行排除,排除的时候还要指定该类的此方法,例如上面既勾选类名,又勾选方法,就可以了。更深层次的原因,推测可能是程序集信息和程序集本身是同一层;而代码中用反射获取方法,外部再用反射混淆就是两层了,所以会失败。

另外一点需要注意的是,请用相同版本生成的exe来打开,例如我用VS2010开发的基于.net framwork4.0的软件,用VS2019打开并生成exe,在Dotfuscator4.9中打开就会报错,startIndex不能大于字符串长度,同理改为net framwork4.5生成软件也会报此错

解决方式就是用VS2010重新生成,之后在Dotfuscator4.9中打开就没有问题了。理解起来就是,你是用什么环境创造的,就应当用同样的环境混淆(伪装)它。
————————————————
版权声明:本文为CSDN博主「习明然」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014650759/article/details/90448074

原文地址:https://www.cnblogs.com/xietianjiao/p/15035299.html