Dotfuscator 不支持 Unity3d?

Dotfuscator doesn't support Unity3d?

我用一些用 C# 编写的 DLL 测试了 Dotfuscator。 它似乎在 .NET 环境中运行良好,所以这次我用 Unity3D 尝试了它们。这些简单的 DLL 仅使用简单的标准 C# classes 和方法进行编码,没有反射,没有 LINQ,没有其他自定义或第三方 API,包括 Unity 的。但未能使它们在我的 Unity3d 项目中工作,而未混淆的原始纯 DLL 工作正常。 挣扎了几个小时后,我决定用新的简单项目进行测试。以下是我在 C# 中得到的所有内容,没有其他代码,根本没有其他参考。

[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:Get () 中的无效 IL 代码:IL_000c:pop”。

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

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

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

我说的对吗?有没有人把 Dotfuscator 和 Unity3D 或 Mono 一起用的好?

[编辑] 我使用 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

更新:从版本 6.0 开始,Dotfuscator Professional 不再支持 Unity。 (参见 changelog for 6.0.0-beta)。它继续支持 Mono。原答案如下。


是的,Dotfuscator Professional Edition 支持 Mono 和 Unity。您在 IL 中看到差异的原因是专业版提供的 Control Flow 混淆。这与您已从中排除标识符的 重命名 功能不同。

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

在 GUI 中加载 Dotfuscator 项目后,可以在 "Advanced" 下的“设置”选项卡上找到此选项,名称为 "Use only Mono-compatible transforms"。将此选项设置为 "Yes",然后保存并重建项目。

如果这仍然给您带来问题,您可以完全禁用控制流以查看是否可以解决问题。这也位于 "Features"、"Disable Control Flow" 下的“设置”选项卡上。将此选项设置为 "Yes",然后保存并重建项目。

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