• 标 题:.Net环境下的程序破解(3)  
  • 作 者:windcbf
  • 时 间:2003/06/17 12:06pm
  • 链 接:http://bbs.pediy.com

一直忙于论文,所以写到(2)就没有写下去了,最近刚好有点时间,就继续我们的《.net环境下的程序破解》系列教程。
现在.net应该是个比较流行的平台了,网上已经开始大量出现.net的控件和服务器软件,我想我们做破解的也应该紧跟时代潮流,呵呵:)
本次主要将如何来静态分析,并且爆破一个很简单的CrackMe。
使用的工具是.net Framework SDK自带的工具,ILasm、ILDasm,,这两个工具用于.net下的汇编、反汇编,具体基本概念和工具用法参见教程(1,2),CrackMe 在附件中。

该CrackMe注册码正确试弹出对话框“Congratulations,Right Code!”,否则为"Wrong Code"。
下面讲解如何破解该CrackMe:
(1)首先启动ILDasm,导入CrackMe.exe .

(2)使用菜单 "File"->"Dump" (中文版的为 "文件"—>"转储"),将程序的IL代码导出为crackme.il
用文本编辑软件打开crackme.il ,搜索"Congratulations,Right Code",定位到这里,
下面我用注释来解释这段IL的含义:

.method private hidebysig
           instance void  button1_Click(object sender,
                                        class [mscorlib]System.EventArgse) cil managed
   {

     .maxstack  2
     .locals  init (string V_0)
     IL_0000:  ldarg.0
     IL_0001:  ldfld      class [System.Windows.forms]System.Windows.forms.TextBox CrackMe.form1::textBox1
     IL_0006:  callvirt   instance string [System.Windows.forms]System.Windows.forms.Control::get_Text()   //取textBox1的Text
     IL_000b:  stloc.0
     IL_000c:  ldloc.0
     IL_000d:  ldstr      "CCG-20030617"
     IL_0012:  callvirt   instance bool [mscorlib]System.String::Equals(string)
     IL_0017:  brfalse.s  IL_002a  //这里是关键跳转,我想大家都看出来了

     IL_0019:  ldstr      "Congratulations,Right Code!"
     IL_001e:  ldstr      "CrackMe"
     IL_0023:  call       valuetype [System.Windows.forms]System.Windows.forms.DialogResult[System.Windows.forms]System.Windows.forms.MessageBox::Show(string,string)  //MessageBox
     IL_0028:  pop
     IL_0029:  ret                      //返回 return

     IL_002a:  ldstr      "Wrong Code!"
     IL_002f:  ldstr      "CrackMe"
     IL_0034:  call       valuetype [System.Windows.forms]System.Windows.forms.DialogResult[System.Windows.forms]System.Windows.forms.MessageBox::Show(string,string)  //MessageBox
     IL_0039:  pop
     IL_003a:  ret
   } // end of method form1::button1_Click  <---这是ILDasm自动生成的,告诉你这是button1按下去对应的

这里我想大家就算不懂IL,也能猜出来这段代码的含义,特别是IL_0017:  brfalse.s  IL_002a,一看就是跳转语句,典型的if .. else 判断。 当然,大家也猜出来注册码是"CCG-20030617" 了

不过我想还是要解释一下IL里面的跳转语句,这是Crack必备知识。

BRTRUE 和BRFALSE ((branch on false/branch on true)是常用的跳转语句,BRTRUE 和BRFALSE弹出堆栈最顶端的条目,然后根据该项为真(1)还是为假(0)而分别跳到指定的代码行。
大家注意到IL_0017: brfalse.s IL_002a的上一条指令是Call String::Equals函数(事实上就是strcmp),返回一个bool值,这个bool值存放在堆栈,然后brfalse把刚刚放进去的bool值从堆栈弹出来,判断如果是假,则跳转到IL_002a (也就是MessageBox提示出错的地方)。

常用的跳转指令还有:
BEQBranch on equal
BGTBranch on greater than or equal
BLEBranch on less than or equal
BLTBranch on less than
BNEBranch on not equal

这几条指令和win32平台的跳转指令都是对应的,我就不一一讲解了。

(3)爆破
这个CrackME是非常简单的,一眼就可以看出注册码,然而现实是残酷的,所以我们还要学会TNT来使自己可以面对生活的挑战:)。
当你还没有熟练IL的基本语法时,我想找到关键点并且爆破是最简单有效的办法。
刚才这个CrackME我们已经找到关键点了,我们把brfalse.s改成brtrue就能轻松爆破了。
然而,问题是你修改的是反汇编出来的il文件,并不是exe,怎么办?
这个问题.net framework sdk里面早就准备好了解决方法,既然有ildasm就有ilasm。

我们对crackme.il做了如下修改:
IL_0017: brtrue.s IL_002a
保存。

ilasm是命令行方式的,我们使用命令:
E:\CrackWork>ilasm Crackme.il /resource=Crackme.res

马上得到下面结果:
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.
Assembling 'E:\CrackWork\Crackme.il' , n
o listing file, to EXE --> 'E:\CrackWork\Crackme.EXE'
Source file is UTF-8

Assembled method form1::.ctor
Assembled method form1::Dispose
Assembled method form1::InitializeComponent
Assembled method form1::Main
Assembled method form1::button1_Click
Creating PE file

Emitting members:
Global
Class 1 Fields: 5; Methods: 5;
Resolving member refs: 37 -> 37 defs, 0 refs
Writing PE file
Operation completed successfully

马上就生成了CrackMe.exe文件,注意上面的参数中还要带上资源文件/resource=Crackme.res ,这个资源文件在ildasm进行反编译的时候自动生成,嘿嘿,大家一定又会想到,我们还可以利用这种方法来修改资源和汉化。
运行新的CrackMe.exe,输入任意字符串(只要不是正确的^_^),都能成功注册。
(CrackMe1.exe 插图)

好了,一个简单的CrackMe就这样搞定了,是不是觉得余味未尽啊,那不妨找一个软件来练练手:)

下次写写如何动态调试.net下的程序,掌握了动态调试后,“调试”程序就更爽了~~ :)


WinHack 2003-6-16
QQ :85436
属于[CCG],[OCN],[YCG],[FCG]