Resco MobileForms Toolkit 2010的破解(转)

五 一期间哪也没去,潜心研究了一下C#. 以前写Win程序一直在用C+SDK,程序小而快,但写起来太麻烦,80%的时间都用在了UI上。MFC不对我的胃口,看过一眼就扔掉了。我最早接触的是 VB,画图一样的编程和简洁明快的语法让我一直很怀念,MFC既没有VB的开发效率又没有SDK的运行效率,在这种情况下我宁可用SDK. 反正我又不是IT专业的,不需要写太大的win程序。
   经典VB在VB6之后断档,变成了VB.NET,当初觉得变化太大无法适应(主要是不能用API了)所以转向了VC. 这次心血来潮学C#,看了一下简介就顿生“this is it”之感——我要的就是这个!作为编程语言家族中的晚辈,C#继承了前辈的各种优点,语法相当优雅,比如我一直无比怀念的Property Let和Property Get终于在C-like语言中得以实现,不必再使用丑陋的get_a()和set_a()这种东西了。从C++转向C#也不用费太多力气,现用现学都来 得及。
   以前写程序片面追求效率,现在想开了,对非运算密集型的Win应用程序而言,花在UI上的执行时间远大于数据运算,在这种情况下 productivity才是最重要的,现在用VC#终于找到了当年用VB写程序的感觉。中间用C+SDK的几年也不算浪费,毕竟了解系统的底层运作方式 还是挺有用处的。

  本文仅限于.NET学习研究目的,严禁用于商业用途。本人不会以任何形式传播RMT破解后的二进制版本,请勿留言或来信索要;本人不为本文提供任何形式的技术支持。
  最 近在写一个用于WM6的.NET CF程序,希望能够实现指划操作。这种功能如果用native code实现是要死人的,.NET CF下倒是有不少好办法。一个开源的实现见Codeproject上的Fluid(作者已将控件部分放到fluid.codeplex.com),不过由 于是强大的作者自娱自乐的产品,虽然能用,但文档几乎没有,用起来很麻烦。在网上找来找去,发现Resco MobileForms Toolkit(下简称RMT)这个神器,但是最新的2010版只有evaluation,看了一下的确不错,但是最便宜的license也要将近一千 刀……Google倒是能找到不少结果,不过都是各类下载网站骗流量的。无奈之下只好自己动手丰衣足食,尝试crack一下,顺便了解一下.NET的工作 机理。

  RMT 2010的保护方式是:设计器只能用30天,控件不限时间,但是每次运行时都有消息框提示。设计器的时间限制比较简单,信息就存放在注册表 HKCU\Software\Resco\Resco MobileForms Toolkit的默认值中,只要在新安装后将其保存起来,定期导回注册表即可。重点在于控件的crack,具体说来就是消除evaluation消息框。
  .NET 程序的托管代码被“编译”为伪汇编代码(MSIL),由实时编译器(JIT)在运行时进一步翻译为本机代码。MSIL与原程序几乎是一一对应的,有很多强 大的反汇编工具, 如著名的Reflector. 用Reflector打开RMT的dll一看,程序并没有混淆,Resco实在太厚道了。
以 AdvancedList为例,用Reflector导出其C#代码,搜索消息框中的Evaluation字样,很容易确定“罪魁祸首”是 RescoLicenseMessage::ShowEvaluationMessage(),下面用反汇编方法修改其内容,去掉弹出的消息框。
  以下操作以.NET CF 3.5版本(\NET35\CF目录下)为例,均在“Visual Studio 命令提示”环境(在开始菜单里找)中完成。
  用ildasm反汇编Resco.AdvancedList.CF3.dll:


ildasm /utf8 /out=Resco.AdvancedList.CF3.il Resco.AdvancedList.CF3.dll


找个文本编辑器打开生成的Resco.AdvancedList.CF3.il,定位到上面的函数:


.method assembly hidebysig static void  ShowEvaluationMessage(class [mscorlib]System.Type 'type', string text) cil managed
{
  // 代码大小       29 (0x1d)
  .maxstack  8
  IL_0000:  ldsfld     string Resco.Controls.AdvancedList.RescoLicenseMessage::MsgEval
  IL_0005:  ldarg.0
  IL_0006:  callvirt   instance string [mscorlib]System.Reflection.MemberInfo::get_Name()
  IL_000b:  ldarg.1
  IL_000c:  call       string [mscorlib]System.String::Format(string,
                                                              object,
                                                              object)
  IL_0011:  ldsfld     string Resco.Controls.AdvancedList.RescoLicenseMessage::MsgEvalVersion
  IL_0016:  call       valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string, string)
  IL_001b:  pop
  IL_001c:  ret
} // end of method RescoLicenseMessage::ShowEvaluationMessage


这个就是MSIL,看起来很像汇编吧?前面的IL_0000等都是标号,用于跳转,不写也可以。要不弹出消息框,让子程序直接返回即可,也就是只留一句ret:


.method assembly hidebysig static void  ShowEvaluationMessage(class [mscorlib]System.Type 'type', string text) cil managed
{
  // 代码大小       29 (0x1d)
  .maxstack  8
  IL_0000:  ret
} // end of method RescoLicenseMessage::ShowEvaluationMessage


  保存文件,下面将其重新编译为dll. 由于原dll用了强命名(strong name),需要自己生成一个密钥对:


sn -k key.snk


并用此密钥对给编译得到的dll签名,否则生成的dll将不可用:


ilasm /dll /key=key.snk /res=Resco.AdvancedList.CF3.res Resco.AdvancedList.CF3.il



  用在.NET CF中的dll还需要额外签几个dll,即DesignerMetadata目录中以asmmeta结尾的三个dll. 对于AdvancedList而言是以下三个:
Resco.AdvancedList.CF3.PocketPC.asmmeta.dll
Resco.AdvancedList.CF3.SmartPhone.asmmeta.dll
Resco.AdvancedList.CF3.WindowsCE.asmmeta.dll
  用ildasm反汇编后用ilasm重新编译,用前面生成的密钥对签名。VS中的工具箱可能没有AdvancedList,重置一下工具箱即可。现在AdvancedList应该可用了,运行时不弹出消息框。

  用这种方法可破解所有控件。可以用循环语句批量反汇编:


for %i in (*.dll) do ildasm /utf8 /out=%~ni.il %i


  注意有几个native dll无法反汇编(文件名中有Native字样),记得删掉生成的il.
  逐 个修改生成的MSIL,大部分控件的crack方法与AdvancedList一样,在 RescoLicenseMessage::ShowEvaluationMessage()函数体中留一句ret即可。Audio、Zip和 ImageBox控件不太一样,ImageBox似乎没有保护(未验证),Zip的修改点在ZipArchive::.cctor()和 ZipStream::.cctor(),Audio控件的修改点在Evaluation::.cctor(),总之盯着“evaluation”和 “MessageBox::Show”字样就没错,都不是很难改。
  全部搞定以后批量编译:


for %i in (*.il) do ilasm /dll /key=key.snk /res=%~ni.res %i /quiet
cd
DesignerMetadata
for %i in (*.asmmeta.dll) do ildasm /utf8 /out=%~ni.il %i
for %i in (*.il) do ilasm /dll /key=key.snk /res=
%~ni.res %i /quiet


  注意有几个dll无法通过PEVerify,不用担心,原来的dll也通不过……
  到VS里重置一下工具箱应该就能用了。

  总 结一下.NET程序的破解,整体上来说要比native程序容易一些,因为可以用Reflector方便地定位再反汇编破解,即使有名称混淆也要比直接读 汇编容易得多。虽然强命名带来了一些麻烦,但重新签名的难度也不是很大。像RMT这种弹出消息框的应该属于最容易crack的,盯着消息框的文字和 MessageBox::Show就行了;如果有license认证,一般都能找到验证license的函数如bool IsValid()这种,将其函数体改成ldc.i4.1; ret两句MSIL(即return true)即可。对付这种破解的方法也很简单,只需要在.NET程序中加入一些native代码,这种混合模式的程序可以用ildasm反汇编,但结果无 法用ilasm编译。不过很显然,这是防不住keygen的。

posted @ 2011-01-20 08:39  董雨  阅读(1056)  评论(0编辑  收藏  举报