【文章标题】: 一个.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[i];
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 [mscorlib]System.String::op_Equality(string,
string)//这里比较随机生成数字的与输入的数字是否相等
IL_002a: brfalse.s IL_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]System.Windows.Forms.Control::Show()
IL_0038: ret
IL_0039: ldarg.0
IL_003a: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox ReWrits_cm8.Form1::textBox1
IL_003f: ldstr "Wrong Password!"
IL_0044: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)
IL_0049: ret
IL_002a: brfalse.s IL_0039//这里跳往IL_002c就可以了:IL_002a: brfalse.s IL_002c
这里虽然爆破了可是还没达到作者的要求。。you just have to patch it so it shows
the correct password in the (gray)textbox。。他要我们把正确的密码显示出来。。
那我们就要手动添加代码了。。。
UltraEdit中编辑: IL_0025: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_002a: brfalse.s IL_002c
IL_002c: ldarg.0
IL_002d: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox ReWrits_cm8.Form1::textBox2//显示密码的控件
IL_0032: ldloca.s V_0 //V_0就是保存随机数的变量了
IL_0034: call instance string [mscorlib]System.Int32::ToString()//将随机生成的数字转化成字符串
IL_0039: callvirt instance void [System.Windows.Forms]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]System.Windows.Forms.Control::Show()
IL_004a: ret
IL_004b: ldarg.0
IL_004c: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox ReWrits_cm8.Form1::textBox1
IL_0051: ldstr "Wrong Password!"
IL_0056: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)
IL_006b: ret
有人要问了V_0怎么就是保存随机数的变量了呢?
看ildasm吧: .method private hidebysig instance void button1_Click(object sender,
class [mscorlib]System.EventArgs e) cil managed
{
// 代码大小 74 (0x4a)
.maxstack 3
.locals init (class [mscorlib]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 [mscorlib]System.String::op_Equality(string,
string)//关键比较
IL_006b: brfalse.s IL_007e//不等跳向错误提示
IL_006d: ldstr "Good Job!"
IL_0072: ldstr "Good Boy!"
IL_0077: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]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]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string,
string)
IL_008d: pop
IL_008e: ret
爆破点: IL_006b: brfalse.s IL_007e//同样改成跳往下一句:IL_006b: brfalse.s IL_006d。。。不管相不相等都跳往下句
修改程序使得正确密码在textbox中显示。。。
UltraEdit中编辑: IL_006b: brfalse.s IL_006d
IL_006d: ldarg.0
IL_006e: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox ReWrits_cm8.Form2::textBox3//显示正确密码的控件。。用Reflector可以在资源中看到textBox3为显示密码控件
IL_0073: ldloca.s V_2 //根据上下文可以看到V_2为正确密码
IL_0075: call instance string [mscorlib]System.Int32::ToString()//转化为字符串
IL_007a: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)
IL_007f: ldstr "Good Job!"
IL_0084: ldstr "Good Boy!"
IL_0089: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]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]System.Windows.Forms.DialogResult [System.Windows.Forms]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 |