2016-07-29 41 views
0

我用一些用C#编写的DLL测试了Dotfuscator。 它似乎在.NET环境下效果很好,所以这次我用Unity3D试了一下。这些简单的DLL只是用简单的标准C#类和方法进行编码,没有反射,没有LINQ,没有其他自定义或第三方API(包括Unity的)。但未能让他们在我的Unity3d项目中工作,而未被模糊处理的原始纯DLL工作正常。 经过几个小时的挣扎后,我决定用新的简单项目进行测试。下面是我在C#中获得的所有内容,没有其他代码,根本没有其他参考。Dotfuscator不支持Unity3d?

[System.Reflection.Obfuscation(Feature = "renaming", Exclude = true)] 
public class Class1 
{ 
    [System.Reflection.Obfuscation(Feature = "renaming", Exclude = true)] 
    public static int Get() 
    { 
     return 123; 
    } 
} 

把这个编译成DLL之后,我把它放在Unity3D Editor的EMPTY项目中并播放,效果很好。但是,当我用Dotfuscator混淆DLL后再次尝试时,它停止说“InvalidProgramException:Class1中的IL代码无效:Get():IL_000c:pop”。

正如您在上面看到的,我添加了防止代码被重命名的属性,当然,我可以在Reflector中看到类和方法的名称实际上未被重命名。

昨天我新注册并从PreEmptive网站下载了最新的Dotfuscator专业版4.21.0评估版。我使用.NET 3.5编译了Visual Studio 2008和2015,并尝试了所有不同的解决方案平台。 Unity的版本是5.3.4f1。

我现在的猜测是Dotfuscator只适用于MSIL,而不是Unity3D内部使用的Mono 2.X。

我对不对?有没有人在Unity3D或Mono中使用Dotfuscator?

[编辑] 我使用ILDasm检查IL代码,不明白发生了什么,但有趣的是看到一堆代码被修改。

前申请Dotfuscator的

.method public hidebysig static int32 Get() cil managed 
{ 
    .custom instance void [mscorlib]System.Reflection.ObfuscationAttribute::.ctor() = (01 00 02 00 54 0E 07 46 65 61 74 75 72 65 08 72 // ....T..Feature.r 
                         65 6E 61 6D 69 6E 67 54 02 07 45 78 63 6C 75 64 // enamingT..Exclud 
                         65 01)           // e. 
    // Code Size  6 (0x6) 
    .maxstack 8 
    IL_0000: ldc.i4  0x75bcd15 
    IL_0005: ret 
} // end of method Class1::Get 

应用Dotfuscator的

.method public hidebysig static int32 Get() cil managed 
{ 
    // Code Size  127 (0x7f) 
    .maxstack 2 
    .locals init (int32 V_0) 
    IL_0000: ldc.i4  0x993 
    IL_0005: stloc  V_0 
    IL_0009: ldloca  V_0 
    IL_000d: ldind.i4 
    IL_000e: ldc.i4  0x993 
    IL_0013: stloc  V_0 
    IL_0017: ldloca  V_0 
    IL_001b: ldind.i4 
    IL_001c: ceq 
    IL_001e: switch  ( 
         IL_002f, 
         IL_004c, 
         IL_002f) 
    IL_002f: br.s  IL_003e 
    IL_0031: ldc.i4.0 
    IL_0032: stloc  V_0 
    IL_0036: ldloca  V_0 
    IL_003a: ldind.i4 
    IL_003b: pop 
    IL_003c: br.s  IL_004a 
    IL_003e: ldc.i4.0 
    IL_003f: stloc  V_0 
    IL_0043: ldloca  V_0 
    IL_0047: ldind.i4 
    IL_0048: br.s  IL_003b 
    IL_004a: nop 
    IL_004b: nop 
    IL_004c: ldc.i4  0x1 
    IL_0051: stloc  V_0 
    IL_0055: ldloca  V_0 
    IL_0059: ldind.i4 
    IL_005a: br.s  IL_0068 
    IL_005c: ldc.i4.0 
    IL_005d: stloc  V_0 
    IL_0061: ldloca  V_0 
    IL_0065: ldind.i4 
    IL_0066: br.s  IL_0068 
    IL_0068: brfalse.s IL_006a 
    IL_006a: ldc.i4.0 
    IL_006b: stloc  V_0 
    IL_006f: ldloca  V_0 
    IL_0073: ldind.i4 
    IL_0074: brfalse IL_0079 
    IL_0079: ldc.i4  0x75bcd15 
    IL_007e: ret 
} // end of method Class1::Get 
+0

你有没有尝试在MonoDevelop(与Unity合作)中创建新的Mono 2项目,并测试你的DLL?如果它能工作,问题在于Unity,如果不是的话,问题在于Mono和/或Mono版本统一使用。 –

+0

@JerrySwitalski谢谢。正如你所说,我认为这是值得尝试的,当我回到家时会检查它:)顺便说一下,单声道2.X版本现在可用? Unity使用老版本的Mono,所以如果不是这样的话,它可能会有所不同。 – Jenix

回答

4

是后,Dotfuscator的专业版支持单声道和统一。您在IL中看到差异的原因是由专业版提供的模糊处理造成的控制流程。这与您从中排除标识符的重命名功能不同。

默认情况下,Dotfuscator使用尽可能多的控制流转换,因为它可以在.NET Framework上使用(即Microsoft的实现)。 但是,其中一些转换与Mono不兼容。 Dotfuscator提供了一个选项来禁用这种转换。

在GUI中加载Dotfuscator项目后,可以在“高级”下的“设置”选项卡上找到该选项,名为“仅使用单一兼容转换”。将此选项设置为“是”,然后保存并重建项目。

Dotfuscator Professional Edition - Settings Tab, "Use only Mono-compatible transforms" enabled and highlighted

如果这仍然是给你的问题,你可以禁用控制流完全,看看是否能解决问题。这也在“设置”选项卡的“功能”,“禁用控制流”下。将此选项设置为“是”,然后保存并重建项目。

完全披露:我在PreEmptive Solutions的Dotfuscator团队工作。如果您有更多问题,请记住像您这样的评估用户也可以完全访问PreEmptive支持

+0

我问过PreEmptive支持团队之后就问这里。我不得不在这里添加这个stackoverflow链接,因为在网站上的一个小盒子里写上所有的代码是很困难的。令我失望的是,他甚至没有查看我要求查看的这一页。此外,他/她只写了四个简短的句子,只是说他/她不确定为什么我不能工作,因为它应该支持Unity3d。但无论如何,来自同一个团队的答案拯救了我的一天,感谢一百万,乔。 – Jenix

+0

非常感谢!我刚刚测试并解决了问题。最重要的是,当我打开“Suppress Ildasm”选项时,它阻止ILDasm完美地打开文件!非常令人印象深刻,是有史以来最好的混淆器。非常喜欢! – Jenix

+0

对不起,但我可以问两个更快的问题吗? 1.“Suppress Ildasm”选项是否会影响性能? 2.有没有关于如何使用Unity3d的教程? – Jenix