creantan 发表于 2009-2-18 11:17

一个.NET CM分析(ReWrit__s_Crackme__8)

【文章标题】: 一个.NET CM分析(ReWrit__s_Crackme__8)
【文章作者】: creantan
【作者邮箱】: creantan@126.com
【作者主页】: www.crack-me.com
【下载地址】: www.crackmes.de
【编写语言】: Microsoft Visual C# / Basic .NET
【使用工具】: Reflector,ildasm,ilasm,UltraEdit
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
第一次分析dotNET的CM。。呵呵。。。简单的一个CM适合对dotNet破解不熟的菜菜。。大鸟飞过。。
crackmes.de随便找了个没人玩的CM
ReWrit's Crackme #8

Kinda easy crackme...
you just have to patch it so it shows
the correct password in the (gray)textbox
and remove the nag...
CM作者叫我们patch这个CM使得正确的密码在灰色textbox中显示,同时去除NAG
先运行程序看下什么情况,发现程序每个几秒NAG就会出现
Reflector载入程序:

发现有两个窗口:FORM1和FORM2
FORM1就是一开始出现的窗口了。。。
FORM2就是第一次输入正确密码的时候点OK按钮后出现的第二个窗口
我们先找NAG的信息
双击FROM1中InitializeComponent()方法,反汇编窗口中显示如下:
private void InitializeComponent()
{
      this.components = new Container();
      ComponentResourceManager manager = new ComponentResourceManager(typeof(Form1));
      this.button1 = new Button();
      this.textBox1 = new TextBox();
      this.label1 = new Label();
      this.label2 = new Label();
      this.textBox2 = new TextBox();
      this.timer1 = new Timer(this.components);//定义一个定时器
      base.SuspendLayout();
      manager.ApplyResources(this.button1, "button1");
      this.button1.Name = "button1";
      this.button1.UseVisualStyleBackColor = true;
      this.button1.Click += new EventHandler(this.button1_Click);
      manager.ApplyResources(this.textBox1, "textBox1");
      this.textBox1.Name = "textBox1";
      manager.ApplyResources(this.label1, "label1");
      this.label1.Name = "label1";
      manager.ApplyResources(this.label2, "label2");
      this.label2.Name = "label2";
      manager.ApplyResources(this.textBox2, "textBox2");
      this.textBox2.Name = "textBox2";
      this.textBox2.ReadOnly = true;
      this.timer1.Interval = 0x2710;       //设置时间为10秒
      this.timer1.Tick += new EventHandler(this.timer1_Tick);//这里双击timer1_Tick
      manager.ApplyResources(this, "$this");
      base.AutoScaleMode = AutoScaleMode.Font;
      base.Controls.Add(this.textBox2);
      base.Controls.Add(this.label2);
      base.Controls.Add(this.label1);
      base.Controls.Add(this.textBox1);
      base.Controls.Add(this.button1);
      base.FormBorderStyle = FormBorderStyle.FixedDialog;
      base.MaximizeBox = false;
      base.MinimizeBox = false;
      base.Name = "Form1";
      base.Load += new EventHandler(this.Form1_Load);
      base.ResumeLayout(false);
      base.PerformLayout();
}

private void timer1_Tick(object sender, EventArgs e)
{
      MessageBox.Show("NAG!", "NAG!");//NAG!找到了
}

接下来找第一个密码:
找到 button1_Click(object sender, EventArgs e)
private void button1_Click(object sender, EventArgs e)
{
      int num = new Random().Next(0, 0x4c4b40);//取0-0x4c4b40之间的随机数。。。
      if (this.textBox1.Text == num.ToString())//比较输入的数字和随机生成的数字比较是否相等
      {
          new Form2().Show();//相等第二个窗口出现
      }
      else
      {
          this.textBox1.Text = "Wrong Password!";//错误显示“Wrong Password!”
      }
}
接下来再找第二个关键算法:
展开FORM2窗口找到private void button1_Click(object sender, EventArgs e)
private void button1_Click(object sender, EventArgs e)
{
      int length = this.textBox1.Text.Length;//取name的长度
      int num2 = 0;
      int num3 = 0;
      for (int i = 0; i < length; i++)//一个小循环
      {
          num2 += this.textBox1.Text;
          num2 *= i;
      }
      int num5 = new Random().Next(0, 0x1388);//取0-0x1388之间的随机数
      num3 = num2 * num5;
      if (this.textBox2.Text == num3.ToString())//判断输入的密码是否与算出的num3相等
      {
          MessageBox.Show("Good Job!", "Good Boy!");
      }
      else
      {
          MessageBox.Show("Wrong Password!", "Bad Boy!");
      }
}
到这里关键的地方都找到了。。现在开始手动修改程序。。。

打开ildasm,载入CM
先ctrl+D dump出来生成中间代码文件,取名为cm.il

用UltraEdit打开cm.il
在ildasm中找到timer1_Tick(object sender, EventArgs e)方法

然后复制一行去UltraEdit中搜索

IL_0000:ldstr      "NAG!"//直接ret就可以了:IL_0000:ret这样NAG就解决了
随机生成的密码我们接下来就爆破吧。。
ildasm中找到FORM1中button1_Click(object sender, EventArgs e)方法

找到关键点:
    IL_0025:call       bool System.String::op_Equality(string,
                                                                   string)//这里比较随机生成数字的与输入的数字是否相等
    IL_002a:brfalse.sIL_0039//不等就跳向IL_0039
    IL_002c:newobj   instance void ReWrits_cm8.Form2::.ctor()
    IL_0031:stloc.2
    IL_0032:ldloc.2
    IL_0033:callvirt   instance void System.Windows.Forms.Control::Show()
    IL_0038:ret
    IL_0039:ldarg.0
    IL_003a:ldfld      class System.Windows.Forms.TextBox ReWrits_cm8.Form1::textBox1
    IL_003f:ldstr      "Wrong Password!"
    IL_0044:callvirt   instance void System.Windows.Forms.Control::set_Text(string)
    IL_0049:ret


    IL_002a:brfalse.sIL_0039//这里跳往IL_002c就可以了:IL_002a:brfalse.sIL_002c
这里虽然爆破了可是还没达到作者的要求。。you just have to patch it so it shows
the correct password in the (gray)textbox。。他要我们把正确的密码显示出来。。
那我们就要手动添加代码了。。。
UltraEdit中编辑:
IL_0025:call       bool System.String::op_Equality(string,
                                                                   string)
IL_002a:brfalse.sIL_002c
IL_002c:ldarg.0
IL_002d:ldfld      class System.Windows.Forms.TextBox ReWrits_cm8.Form1::textBox2//显示密码的控件
IL_0032:ldloca.s   V_0 //V_0就是保存随机数的变量了
IL_0034:call       instance string System.Int32::ToString()//将随机生成的数字转化成字符串
IL_0039:callvirt   instance void System.Windows.Forms.Control::set_Text(string)//这就是textBox2.Text=V_0
IL_003e:newobj   instance void ReWrits_cm8.Form2::.ctor()
IL_0043:stloc.2
IL_0044:ldloc.2
IL_0045:callvirt   instance void System.Windows.Forms.Control::Show()
IL_004a:ret
IL_004b:ldarg.0
IL_004c:ldfld      class System.Windows.Forms.TextBox ReWrits_cm8.Form1::textBox1
IL_0051:ldstr      "Wrong Password!"
IL_0056:callvirt   instance void System.Windows.Forms.Control::set_Text(string)
IL_006b:ret
有人要问了V_0怎么就是保存随机数的变量了呢?
看ildasm吧:
.method private hidebysig instance voidbutton1_Click(object sender,
                                                         class System.EventArgs e) cil managed
{
    // 代码大小       74 (0x4a)
    .maxstack3
    .locals init (class System.Random V_0,
             int32 V_1,
             class ReWrits_cm8.Form2 V_2)//这里就是用到的局部变量:System.Random V_0

现在来改第二个窗口:
ildasm中找到FORM2中button1_Click(object sender, EventArgs e)方法

找到关键点:
IL_0066:call       bool System.String::op_Equality(string,
                                                                   string)//关键比较
    IL_006b:brfalse.sIL_007e//不等跳向错误提示
    IL_006d:ldstr      "Good Job!"
    IL_0072:ldstr      "Good Boy!"
    IL_0077:call       valuetype System.Windows.Forms.DialogResult System.Windows.Forms.MessageBox::Show(string,
                                                                                                                                                       string)
    IL_007c:pop
    IL_007d:ret
    IL_007e:ldstr      "Wrong Password!"
    IL_0083:ldstr      "Bad Boy!"
    IL_0088:call       valuetype System.Windows.Forms.DialogResult System.Windows.Forms.MessageBox::Show(string,
                                                                                                                                                       string)
    IL_008d:pop
    IL_008e:ret

爆破点:
IL_006b:brfalse.sIL_007e//同样改成跳往下一句:IL_006b:brfalse.sIL_006d。。。不管相不相等都跳往下句
修改程序使得正确密码在textbox中显示。。。
UltraEdit中编辑:
IL_006b:brfalse.sIL_006d
IL_006d:ldarg.0
IL_006e:ldfld      class System.Windows.Forms.TextBox ReWrits_cm8.Form2::textBox3//显示正确密码的控件。。用Reflector可以在资源中看到textBox3为显示密码控件
IL_0073:ldloca.s   V_2       //根据上下文可以看到V_2为正确密码
IL_0075:call       instance string System.Int32::ToString()//转化为字符串
IL_007a:callvirt   instance void System.Windows.Forms.Control::set_Text(string)
IL_007f:ldstr      "Good Job!"
IL_0084:ldstr      "Good Boy!"
IL_0089:call       valuetype System.Windows.Forms.DialogResult System.Windows.Forms.MessageBox::Show(string,
IL_008e:pop
IL_008f:ret
IL_0090:ldstr      "Wrong Password!"
IL_0095:ldstr      "Bad Boy!"
IL_009a:call       valuetype System.Windows.Forms.DialogResult System.Windows.Forms.MessageBox::Show(string,
IL_009f:pop
IL_00a0:ret
到这里这个CM基本上就解决了。。。
现在用ilasm来编译:
CMD中输入:ilasm /resource=cm.res cm.il

生成cm.exe文件
运行下:

呵呵。。可以了。。。




--------------------------------------------------------------------------------
【版权声明】: 本文原创于creantan, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年02月02日 10:04:18

cshow 发表于 2009-2-18 12:19

好的
谢谢
网上很少有关于.net的cm的分析
拿回来研究下

wa22 发表于 2009-2-18 12:45

确实不错,希望坚持发点.net有关的实战~

老万 发表于 2009-2-18 20:26

谢谢楼主,收藏了。

datochan 发表于 2009-2-19 00:22

LZ好厉害·~~~~
好崇拜·~~

gy10000 发表于 2009-2-19 09:26

请问下哦2
附件密码多少?

creantan 发表于 2009-2-19 12:58

原帖由 gy10000 于 2009-2-19 09:26 发表 http://bbs.52pojie.cn/images/common/back.gif
请问下哦2
附件密码多少?
没加密码啊。。。。

xie83544109 发表于 2009-2-19 18:15

模拜楼主
一个字牛
:loveliness:

飞天凤凰 发表于 2009-2-19 23:29

不错,顶楼主。

estelle 发表于 2009-2-20 18:02

写外挂的也学习.net啊
页: [1] 2
查看完整版本: 一个.NET CM分析(ReWrit__s_Crackme__8)