Resco MobileForms Toolkit 2010的破解

郭凯
2023-12-01

本文仅限于.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的。

 类似资料: