I tested Dotfuscator with some of my DLLs written in C#. It seemed it works really well on .NET environment, so this time I tried them with Unity3D. Those simple DLLs were just coded only with simple standard C# classes and methods, no reflection, no LINQ, no other custom or 3rd party APIs including Unity's. But failed to make them work in my Unity3d project, while original pure DLLs which aren't obfuscated were working fine. After struggling for a few hours, I decided to test with new simple projects. Below is all I got in C#, there are no other code, no other references at all.
[System.Reflection.Obfuscation(Feature = "renaming", Exclude = true)]
public class Class1
{
[System.Reflection.Obfuscation(Feature = "renaming", Exclude = true)]
public static int Get()
{
return 123;
}
}
After compiling this to DLL, I put it in an EMPTY project on Unity3D Editor and played, and it worked well. But when I gave another try after obfuscating the DLL with Dotfuscator, it stopped saying "InvalidProgramException: Invalid IL code in Class1:Get (): IL_000c: pop".
As you can see above, I added attributes which prevent the code from being renamed, and of course, I could see in Reflector, the name of both class and method weren't actually renamed.
Yesterday I newly registered and downloaded the evaluation version of the latest Dotfuscator Professional Edition 4.21.0 from PreEmptive's site. I compiled both on Visual Studio 2008 and 2015 with .NET 3.5, also tried with all different Solution Platforms. The version of Unity is 5.3.4f1.
My guess now is Dotfuscator only works with MSIL, not Mono 2.X which Unity3D internally uses.
Am I right? Is there anyone using Dotfuscator with Unity3D or Mono well?
[EDIT] I checked IL code using ILDasm, don't understand what's going on, but interesting to see a bunch of code is modified.
Before applying 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
After applying 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
UPDATE: As of version 6.0, Dotfuscator Professional no longer supports Unity. (See changelog for 6.0.0-beta). It continues to support Mono. The original answer follows.
Yes, Dotfuscator Professional Edition supports Mono and Unity. The reason you're seeing differences in the IL is due to the Control Flow obfuscation that Professional Edition provides. This is a distinct from the Renaming feature from which you have excluded your identifiers.
By default, Dotfuscator uses as many Control Flow transforms as it can get away with on the .NET Framework (i.e., Microsoft's implementation). However, some of these transforms are not compatible with Mono. Dotfuscator provides an option to disable such transforms.
After loading your Dotfuscator project in the GUI, this option can be found on the Settings tab, under "Advanced", named "Use only Mono-compatible transforms". Set this option to "Yes", then save and rebuild the project.
If that is still giving you problems, you can disable Control Flow entirely to see if that fixes the problem. This is also on the Settings tab, under "Features", "Disable Control Flow". Set this option to "Yes", then save and rebuild the project.
Full disclosure: I work for the Dotfuscator team at PreEmptive Solutions. If you have more questions, keep in mind that evaluation users like yourself also have full access to PreEmptive support.