收藏订阅
Skater .NET Obfuscator适合那些希望周期性地混淆.NET产品代码的用户。RustemSoft内部也在使用Skater,以保证所有RustemSoft .NET可执行文件和程序集的安全。命令行版本(运行在批量文件模式下)将更方便升级您的预定产品。先在一个图形用户界面版本中为一个程序集分配一些配置,这些配置将在批量混淆文件时使用。
Skater .NET Obfuscator功能介绍 | Skater .NET Obfuscator示例 | Skater .NET Obfuscator各种版本之间的区别
Skater .NET Obfuscator的主要功能
应用程序漏洞、偷窃知识产权和收入损失是现今公司面临的最大威胁。根据商业软件联盟(Business Software Alliance)的数据,世界范围内,软件盗版率达40%。
代码混淆可有效地防止未授权的逆向工程。 任何软件保护技术的主要功能是:检测盗版行为(破解密码或者篡改软件);这些破解密码和篡改软件的行为将使被保护的软件降级到无检测状态,软件保护技术还要防止这种降级情况的发生。
主要的混淆技术:
例子
先写一段简单的命令行应用程序,然后混淆它。下面两段程序分别是VB.NET 和 C# 版的"Hello World!"程序(显示字符串"Hello World!")。实际上,除了显示"Hello World!",它还会显示今天的日期和当下的时间。为了弄清混淆后会有何不同,我们还会加入两个私有变量。
Imports System Module Module1 Private str As String = "Hello World! Today is:" Private today As Date = Now Sub Main() Console.WriteLine(str + CStr(today)) End Sub End Module
using System; struct Module1 { private string str = "Hello World! Today is:"; private System.DateTime today = Now; void Main() { Console.WriteLine(str + System.Convert.ToString(today)); } }
你可以看到四个高亮的成员名。两个是私有变量名:today和str. Module1是类名。Main是一个简单类中的唯一一个方法(method)名。现在我们开始在.NET环境中编译这些简单的代码。编译后,我们可以得到ConsoleApplication1.exe可执行文件。这个可执行文件中包含什么呢?为什么人们认为需要隐藏了.NET中的东西呢?
.NET Framework SDK中有一个反汇编器ILDasm,通过ILDasm,您可将.NET编译语言反编译为IL(.NET框架中的中间语言)程序集语言形式。在命令行中运行ILDasm,您就可以反编译ConsoleApplication1.exe。下图就是反编译后的代码。
.class private auto ansi sealed beforefieldinit Module1 extends [mscorlib]System.Object { .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices. StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .field private static string str .field private static valuetype [mscorlib]System.DateTime today .method private specialname rtspecialname static void .cctor() cil managed { .maxstack 8 IL_0000: ldstr "Hello World! Today is:" IL_0005: stsfld string ConsoleApplication1.Module1::str IL_000a: call valuetype [mscorlib]System.DateTime [Microsoft.VisualBasic]Microsoft. VisualBasic.DateAndTime::get_Now() IL_000f: stsfld valuetype [mscorlib]System.DateTime ConsoleApplication1.Module1::today IL_0014: nop IL_0015: ret } // end of method Module1::.cctor .method public static void Main() cil managed { .entrypoint .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 8 IL_0000: nop IL_0001: ldsfld string ConsoleApplication1.Module1::str IL_0006: ldsfld valuetype [mscorlib]System.DateTime ConsoleApplication1.Module1::today IL_000b: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType:: FromDate(valuetype [mscorlib]System.DateTime) IL_0010: call string [mscorlib]System.String::Concat(string, string) IL_0015: call void [mscorlib]System.Console::WriteLine(string) IL_001a: nop IL_001b: nop IL_001c: ret } // end of method Module1::Main } // end of class Module1
这些IL脚本是不是很清晰,可以读懂呢?也许,对于我们这些菜鸟,这些IL代码确实难懂。但是对于那些真正懂得IL语言的技术专家,这些.NET源程序是小菜一碟。通过一些更高级的反编译器将源代码转换为其他语言,这样更多人能读懂您的源代码。更高级的反编译器可以将.NET程序集直接反编译为高级语言,如C#, VB .NET, 或者 C++.
现在,我们通过Skater .NET Obfuscator混淆这段ConsoleApplication1.exe可执行文件。在Skater Obfuscator中打开这个exe文件,进入用户界面中的Options,然后选择在'Naming Conventions'下的'Alpha-Numeric characters'。选择所有混淆模式下的私人和公共成员。
当您运行混淆后的ConsoleApplication1.exe时,它的运行结果是一样的。让我们看看混淆后,这个简单的程序里发生了什么变化。我们需要再次在ILDasm.exe中运行这个被混淆后的可执行文件(ConsoleApplication1.exe),然后我们可以得到下面IL脚本。
.class private auto ansi sealed beforefieldinit '0AAAA' extends [mscorlib]System.Object { .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices. StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .field private static string '1AAA0' .field private static valuetype [mscorlib]System.DateTime '2AAAA' .method private specialname rtspecialname static void .cctor() cil managed { .maxstack 8 IL_0000: ldstr "Hello World! Today is:" IL_0005: stsfld string ConsoleApplication1.'0AAAA'::'1AAA0' IL_000a: call valuetype [mscorlib]System.DateTime [Microsoft.VisualBasic]Microsoft. VisualBasic.DateAndTime::get_Now() IL_000f: stsfld valuetype [mscorlib]System.DateTime ConsoleApplication1.'0AAAA'::'2AAAA' IL_0014: nop IL_0015: ret } // end of method '0AAAA'::.cctor .method public static void '1AAAA'() cil managed { .entrypoint .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 8 IL_0000: nop IL_0001: ldsfld string ConsoleApplication1.'0AAAA'::'1AAA0' IL_0006: ldsfld valuetype [mscorlib]System.DateTime ConsoleApplication1.'0AAAA'::'2AAAA' IL_000b: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType:: FromDate(valuetype [mscorlib]System.DateTime) IL_0010: call string [mscorlib]System.String::Concat(string, string) IL_0015: call void [mscorlib]System.Console::WriteLine(string) IL_001a: nop IL_001b: nop IL_001c: ret } // end of method '0AAAA'::'1AAAA' } // end of class '0AAAA'
Skater .NET Obfuscator通过阿拉伯数字取代成员名,这使得代码更难理解。但这没什么了不起,每种混淆器都可以做到。每个人都可以用不同的阿拉伯数字取代名称。ILasm.exe是另外一款.NET Framework SDK编译器,可以将IL代码编译成可执行文件代码。通过它,我们可以将被混淆的IL代码反编译成可执行文件。Skater .NET Obfuscator可以生成无法反编译的可执行文件。下面是IL脚本。
.class private auto ansi sealed beforefieldinit '?' extends [mscorlib]System.Object { .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices. StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .field private static string '?' .field private static valuetype [mscorlib]System.DateTime '?' .method private specialname rtspecialname static void .cctor() cil managed { .maxstack 8 IL_0000: ldstr "Hello World! Today is:" IL_0005: stsfld string ConsoleApplication1.'?'::'?' IL_000a: call valuetype [mscorlib]System.DateTime [Microsoft.VisualBasic]Microsoft. VisualBasic.DateAndTime::get_Now() IL_000f: stsfld valuetype [mscorlib]System.DateTime ConsoleApplication1.'?'::'?' IL_0014: nop IL_0015: ret } // end of method '?'::.cctor .method public static void '?'() cil managed { .entrypoint .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 8 IL_0000: nop IL_0001: ldsfld string ConsoleApplication1.'?'::'?' IL_0006: ldsfld valuetype [mscorlib]System.DateTime ConsoleApplication1.'?'::'?' IL_000b: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType:: FromDate(valuetype [mscorlib]System.DateTime) IL_0010: call string [mscorlib]System.String::Concat(string, string) IL_0015: call void [mscorlib]System.Console::WriteLine(string) IL_001a: nop IL_001b: nop IL_001c: ret } // end of method '?'::'?' } // end of class '?'
可以看到,所有的成员名都被'?'代替。很明显,上面的IL代码无法编译,即使编译成了可执行文件也将无法正常运行。通过Skater .NET Obfuscator中的一些特殊设置,很容易得到这样的IL代码。只需进入混淆器界面中的Options,在'Naming Conventions'.下选择'?' characters即可。
Skater .NET Obfuscator通过改变字节码,将那些有意义的方式名(比如Main())用隐藏名(比如'?'())取代。这些新名也称为乱码名。虽然反编译器还是可以将混淆后的字节代码反向转换,但是这些没有意义的乱码名极大地降低了新生成的源程序代码的价值,而且代码很难读懂。这些乱码名还有一个好处,当长的名字被简短的名字代替时,编译代码的长度也变短了。
混淆成员名只是.NET程序集混淆过程中的第一步。为了更好的保护您的.NET应用程序,您还要使用Skater .NET Obfuscator中的其他功能和算法。
Skater .NET混淆器各种版本之间的区别比较:
.NET代码保护可以防止.NET安装源代码进行再编译(没有改变其功能性),并隐藏.NET代码的主要部分。对于需要利用.NET代码保护功能的.NET程序开发者,标准版是一实惠的解决方案。基于标准版,软件开发者可以:
专业版除了具有标准版的功能外,还增加了字符串加密、控制流混淆和.NET链接程序集功能。
终极版为软件开发者提供混淆器的所有功能。除了标准版和专业版的功能外,终极版还提供代码扩展和.NET应用程序授权功能。