这个轻量级控件基本上已经达到了我的要求。不过这么个小控件居然都要收费,19.9美刀。。否则只能使用30天。。那就只好想办法把它Crack掉了。
由于.NET程序集并不直接编译成二进制代码,而是IL中间语言。这种设计势必造成对代码的安全保护降低。网上也有不少讲解破解.NET程序集的方法。其中最简单的就是反射或反编译工具查看代码。相对应的保护措施就是通过混淆器,把类、方法、变量的名称打乱,给破译者造成困难。
一、分析
我们这里使用大众工具Reflector来看看这个XmlEdit.DLL。看到了什么?SmartComponents.Licence和SmartComponents.Xml两个命名空间以及下面的类。说明没有经过混淆器处理,那接下来就容易多了。通过分析代码,我们关注到以下三个类:ExpiringLicense、Globals、XmlEdit。
bool ExpiringLicense.IsExpired { get; }
这个方法用来检查是否过期,我们只要让它永远 return false; 那么就永不过期了:)
bool Globals.HasValidLicense { get; set; }
这个方法设置或返回是否拥有已验证的身份认证,让它永远 return true; 也可以永不过期^^
我们再来看看 XmlEdit.FormatXML() 方法。其中检查了Globals.HasValidLicense,如果它已经被我们改成永远为 true,那么
二、改写DLL
从前面的分析来看,虽然破解的方法很多,但除了在自己的程序里改写注册表外,其余的都需要改变原来控件的代码。下面我们就来看看如何改写DLL。
这里我们要用到的工具其实都是微软在.NET SDK里已经提供的,ILASM和ILDASM,前者用于编译IL代码,后者用于将程序集反编译到IL。这样我们就可以先将XmlEdit.DLL变成IL代码,然后改写IL代码,然后重新编译即可:)
ILDASM 的语法很简单: ILDASM 程序集 /OUT=IL代码文件名
ILDASM XmlEdit.DLL /OUT=XmlEdit.IL
这样我们就得到了IL代码格式的XmlEdit库。然后可以直接修改这个IL文件。我们以最简单的一个破解方法举例,去掉 XmlEdit 构造函数里的 LicenseManager.Validate(typeof(XmlEdit)) 这句代码。
首先我们找到 XmlEdit 的构造函数。构造函数在IL里都是用.ctor()表示的。
|
.class public auto ansi beforefieldinit XmlEdit
IL_0032: ldsfld class [mscorlib]Microsoft.Win32.RegistryKey [mscorlib]Microsoft.Win32.Registry::LocalMachine
} // end .try |
我们把这句话删除即可。
IL_0067: call void [System]System.ComponentModel.LicenseManager::Validate(class [mscorlib]System.Type)
如果你对IL语言很熟的话,你甚至完全可以改变原先代码的逻辑结构。比如我们前面说的让 Globals.HasValidLicense 永远返回 true。只要在IL文件里找到这个方法的定义,然后改一下就可以了。如果你对IL语言不是很熟,这里还有个小技巧,就是自己写一个 bool TestProperty { get { return true; } },然后看看它的IL代码是什么,全部复制过来就可以了:)
最后我们把IL文件重新产生DLL。ILASM的语法是: ILASM IL文件名 /OUT=程序集名称
ILASM XmlEdit.IL /OUT=XmlEdit.DLL
运行这个命令看看,应该会出现一个错误才对,说无法为强名称签名。
原来这个 XmlEdit.DLL 还使用了强名称(StrongNamed)。如果没有 DLL 的发布者所拥有的密钥,是无法对IL进行再编译的。但强名称真的能保护我们的代码吗?不是的!它也很容易破解,或者说,去掉强名称。
我们来看一下IL文件的头部:
| .assembly XmlEdit
{ .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 00 00 00 ) .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 1B 53 6D 61 72 74 43 6F 6D 70 6F 6E 65 6E // ...SmartComponen 74 73 2E 58 6D 6C 2E 58 6D 6C 45 64 69 74 00 00 ) // ts.Xml.XmlEdit.. .custom instance void [mscorlib]System.Reflection.AssemblyKeyFileAttribute::.ctor(string) = ( 01 00 19 2E 2E 5C 2E 2E 5C 2E 2E 5C 43 6F 6D 6D // .....\..\..\Comm 6F 6E 5C 73 67 4B 65 79 2E 73 6E 6B 00 00 ) // on\sgKey.snk.. .custom instance void [mscorlib]System.Reflection.AssemblyDelaySignAttribute::.ctor(bool) = ( 01 00 00 00 00 ) .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 ) .custom instance void [mscorlib]System.Reflection.AssemblyKeyNameAttribute::.ctor(string) = ( 01 00 00 00 00 ) .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 07 58 6D 6C 45 64 69 74 00 00 ) // ...XmlEdit.. .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 10 53 6D 61 72 74 20 43 6F 6D 70 6F 6E 65 // ...Smart Compone 6E 74 73 00 00 ) // nts.. .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 ) .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 30 45 64 69 74 2C 20 73 79 6E 74 61 78 20 // ..0Edit, syntax 68 69 67 68 6C 69 67 68 74 69 6E 67 20 61 6E 64 // highlighting and 20 69 6E 64 65 6E 74 20 58 6D 6C 20 69 6E 20 2E // indent Xml in . 4E 45 54 00 00 ) // NET.. .publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 // .$.............. 00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 // .$..RSA1........ AF 21 9E 12 EE 56 09 80 F5 1A 6D 10 D4 AB EF BA // .!...V....m..... 1F A7 C0 61 5E 99 2A FF EC F0 28 8A 89 D6 4A 88 // ...a^.*...(...J. 56 76 D7 18 D6 5A BE A5 4B 5C 29 29 3B 3D 9C B8 // Vv...Z..K\));=.. 74 F4 5F E2 E4 E0 B6 24 BD 6B EB 6E 89 C0 3E 7E // t._....$.k.n..>~ DB C5 4A EB B1 E6 9D E0 67 D4 08 C8 6E CC 54 5A // ..J.....g...n.TZ 03 31 F0 12 5D A5 E9 12 74 AD AE 50 94 D7 D4 A2 // .1..]...t..P.... 0D 68 05 31 0C 3C FA 9E 0D 4D 47 4B C0 6D 89 91 // .h.1.<...MGK.m.. 0F 8C 72 F2 D2 6A 0C FC E1 4C B6 D1 7D E6 8B E4 ) // ..r..j...L..}... .hash algorithm 0x00008004 .ver 1:0:0:1 } |
在这里我们可以看到这个程序集的所有描述信息,比如Product、Company等等,甚至可以随意修改。更关键的是我们看到了.publicKey,这就是强名称的公钥。我们把这一段全部删掉。重新用ILASM编译,OK,PASS!
以下是本文的相关下载:
XmlEdit 原版安装程序
XmlEdit.DLL 原版
XmlEdit.DLL 破解版
BTW: SourceForge上也有一个不错的开源的并基于.NET的XML编辑器:DINAMIC XML Editor

