[反汇编练习] 160个CrackMe之001。
本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。
其中,文章中按照如下逻辑编排(解决如下问题):
1、使用什么环境和工具
2、程序分析
3、思路分析和破解流程
4、注册机的探索
1、工具和环境:
WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。
160个CrackMe的打包文件。
下载地址: http://pan.baidu.com/s/1xUWOY 密码: jbnq
注:
1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。
2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。
2、程序分析:
想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。
打开CHM文件,将第一个文件 Acid burn.exe 保存下来,新建一个01的文件夹,将exe放到这里,同时将以后的分析文件也存放这里。打开Acid burn.exe,随意输入和点击,熟悉程序流程。
我们发现,这个软件分为了两个部分,一个是Serial/Name,需要输入用户名和注册码才能通过,另外一个Serial只需要输入一个注册码一类的东西。我们随意选一个开始,比如,先进行第一个。
我们随意输入一个用户名和序列号(伪码):
伪码:
Name:112233
Serial:44556677
点击Check it Baby! 它会弹出一个对话框提示: Sorry, The Serial is incorrect !
再换几个随意试试,发现就这一种情况。
OK,出现了对话框这就很好办,说明作者在校验注册码之后发现如果错误了就直接弹窗,我们只要找到弹出对话框的地方,向上跟踪,就可以找出判断是否正确的地方了,jmp或者Nop就算爆破了。
Technorati 标记: 反汇编,注册机,破解,CrackMe
3、具体步骤如下:
我们随意输入一个用户名和序列号(伪码):
伪码:
Name:112233
Serial:44556677
点击Check it Baby! 它会弹出一个对话框提示: Sorry, The Serial is incorrect !
此时不要点击确定按钮,返回OD暂停(F12),点击堆栈-K小图标(Ctrl+K)
如下图:
这里有两个MessageBox的地址,第一个地址为77D5082F这个地址明显太大,不在模块的领空,不是的。第二个地址为0042A1AE,和00400100地址非常接近,十有八九就是它了。
右键 show call, 在Call上面设置断点。
查看附近代码:
0042A170 /$ 55 push ebp
0042A171 |. 8BEC mov ebp,esp
0042A173 |. 83C4 F4 add esp,-0xC
0042A176 |. 53 push ebx
0042A177 |. 56 push esi
0042A178 |. 57 push edi
0042A179 |. 8BF9 mov edi,ecx
0042A17B |. 8BF2 mov esi,edx
0042A17D |. 8BD8 mov ebx,eax
0042A17F |. E8 7CB4FDFF call
int _tmain(int argc, _TCHAR* argv[])
{
printf(“Input Name:\r\n”);
// 取第一个字符值
int cName = getchar();
if ( cName > 0x21) // 只处理可见字符
{
cName *= 0x29; // 乘法
cName *= 2; // 自增一倍
printf(“Serial: CW-%4d-CRACKED\r\n”,cName);
}else{
printf(“input error!\r\n”);
}
system(“pause”);
return 0;
}
第二个单独Serial
流程同第一个,
但是这个很简单,直接在调用CALL那里向上F8走一遍就基本明白了。
核心代码:
CALL之前的那个JNZ是爆破的关键,直接NOP就OK了。
JNZ之前的那个CALL是进行Serial判断的关键,通过单步跟踪发现他就是一个固定值。
代码如下:
0042F470 /. 55 push ebp
0042F471 |. 8BEC mov ebp,esp
0042F473 |. 33C9 xor ecx,ecx
0042F475 |. 51 push ecx
0042F476 |. 51 push ecx
0042F477 |. 51 push ecx
0042F478 |. 51 push ecx
0042F479 |. 53 push ebx
0042F47A |. 8BD8 mov ebx,eax
0042F47C |. 33C0 xor eax,eax
0042F47E |. 55 push ebp
0042F47F |. 68 2CF54200 push 0042F52C
0042F484 |. 64:FF30 push dword ptr fs:[eax]
0042F487 |. 64:8920 mov dword ptr fs:[eax],esp
0042F48A |. 8D45 FC lea eax,[local.1]
0042F48D |. BA 40F54200 mov edx,0042F540 ; ASCII 48,”ello”
0042F492 |. E8 7142FDFF call 00403708
0042F497 |. 8D45 F8 lea eax,[local.2]
0042F49A |. BA 50F54200 mov edx,0042F550 ; ASCII 44,”ude!”
0042F49F |. E8 6442FDFF call 00403708
0042F4A4 |. FF75 FC push [local.1]
0042F4A7 |. 68 60F54200 push 0042F560 ; UNICODE ” ”
0042F4AC |. FF75 F8 push [local.2]
0042F4AF |. 8D45 F4 lea eax,[local.3]
0042F4B2 |. BA 03000000 mov edx,0x3
0042F4B7 |. E8 F044FDFF call 004039AC
0042F4BC |. 8D55 F0 lea edx,[local.4]
0042F4BF |. 8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042F4C5 |. E8 8EB5FEFF call 0041AA58
0042F4CA |. 8B45 F0 mov eax,[local.4] ; // eax=112233
0042F4CD |. 8B55 F4 mov edx,[local.3] ; // edx=Hello Dude!
0042F4D0 |. E8 2745FDFF call 004039FC
0042F4D5 75 1A jnz short 0042F4F1 ; // 爆破的关键
0042F4D7 |. 6A 00 push 0x0
0042F4D9 |. B9 64F54200 mov ecx,0042F564
0042F4DE |. BA 70F54200 mov edx,0042F570
0042F4E3 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042F4E8 |. 8B00 mov eax,dword ptr ds:[eax]
0042F4EA |. E8 81ACFFFF call 0042A170
0042F4EF |. EB 18 jmp short 0042F509
0042F4F1 |> 6A 00 push 0x0
0042F4F3 |. B9 84F54200 mov ecx,0042F584
0042F4F8 |. BA 8CF54200 mov edx,0042F58C
0042F4FD |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042F502 |. 8B00 mov eax,dword ptr ds:[eax]
0042F504 |. E8 67ACFFFF call 0042A170
0042F509 |> 33C0 xor eax,eax
这个没有动态生成的注册码,是一个固定的:Hello Dude!