[反汇编练习] 160个CrackMe之003
本帖最后由 44018723 于 2014-6-11 20:20 编辑[反汇编练习] 160个CrackMe之003。本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将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,选择第3个Afkayas,保存下来。运行程序,程序界面如下:
这是一个标准的Name/Serial注册码方式,二话不说,来个伪码测试:Name: 3333 Serial: 44445555点击OK,弹出了一个错误对话框,You Get Wrong,Try again!
3、思路分析和破解流程:
首先,将程序从OD打开,这次的程序会提示可能有压缩内容,SO,我们不得不使用PEID看看是否有壳,PEID查看情况如下:
有压缩内容,但是没有壳,很好,放心地使用OD打开,直接点是。按照经验,有对话框提示的程序可以通过堆栈查找调用的位置。方法如下:输入伪码,点击OK,弹出错误对话框,此时不要关闭这个对话框,切换到OD,点击暂停程序,然后Ctrl+K到堆栈视图,如下:
更具体的分析就不说了,参看002,直接最后一个rtcMsgBox,右键->show call。
vba相关函数请参考这篇文章。(www.cnblogs.com/bbdxf/p/3780187.html)
将代码直接向上翻看,找到了关键的跳转,JE,代码如下:00408665 .66:85F6 test si,si
00408668 .8945 94 mov dword ptr ss:,eax
0040866B .894D AC mov dword ptr ss:,ecx
0040866E .8945 A4 mov dword ptr ss:,eax
00408671 .894D BC mov dword ptr ss:,ecx
00408674 .8945 B4 mov dword ptr ss:,eax
00408677 74 62 je short 004086DB ;// 爆破的关键
00408679 .8B35 14B14000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaSt>;msvbvm50.__vbaStrCat
0040867F .68 C06F4000 push 00406FC0 ;UNICODE "You Get It"
00408684 .68 DC6F4000 push 00406FDC ;ASCII "\r"
00408689 .FFD6 call esi ;<&MSVBVM50.__vbaStrCat>
0040868B .8BD0 mov edx,eax
0040868D .8D4D E8 lea ecx,dword ptr ss:
00408690 .FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;msvbvm50.__vbaStrMove
00408696 .50 push eax
00408697 .68 E86F4000 push 00406FE8 ;UNICODE "KeyGen It Now"
0040869C .FFD6 call esi
0040869E .8945 CC mov dword ptr ss:,eax
004086A1 .8D45 94 lea eax,dword ptr ss:
004086A4 .8D4D A4 lea ecx,dword ptr ss:
004086A7 .50 push eax
004086A8 .8D55 B4 lea edx,dword ptr ss:
004086AB .51 push ecx
004086AC .52 push edx
004086AD .8D45 C4 lea eax,dword ptr ss:
004086B0 .6A 00 push 0x0
004086B2 .50 push eax
004086B3 .C745 C4 08000>mov dword ptr ss:,0x8
004086BA .FF15 24B14000 call dword ptr ds:[<&MSVBVM50.#595>] ;msvbvm50.rtcMsgBox
004086C0 .8D4D E8 lea ecx,dword ptr ss:
004086C3 .FF15 A8B14000 call dword ptr ds:[<&MSVBVM50.__vbaFreeS>;msvbvm50.__vbaFreeStr
004086C9 .8D4D 94 lea ecx,dword ptr ss:
004086CC .8D55 A4 lea edx,dword ptr ss:
004086CF .51 push ecx
004086D0 .8D45 B4 lea eax,dword ptr ss:
004086D3 .52 push edx
004086D4 .8D4D C4 lea ecx,dword ptr ss:
004086D7 .50 push eax
004086D8 .51 push ecx
004086D9 .EB 60 jmp short 0040873B
004086DB >8B35 14B14000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaSt>;msvbvm50.__vbaStrCat
004086E1 .68 08704000 push 00407008 ;UNICODE "You Get Wrong"
004086E6 .68 DC6F4000 push 00406FDC ;ASCII "\r"
004086EB .FFD6 call esi ;<&MSVBVM50.__vbaStrCat>
004086ED .8BD0 mov edx,eax
004086EF .8D4D E8 lea ecx,dword ptr ss:
004086F2 .FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;msvbvm50.__vbaStrMove
004086F8 .50 push eax
004086F9 .68 28704000 push 00407028 ;UNICODE "Try Again"
004086FE .FFD6 call esi
00408700 .8945 CC mov dword ptr ss:,eax
00408703 .8D55 94 lea edx,dword ptr ss:
00408706 .8D45 A4 lea eax,dword ptr ss:
00408709 .52 push edx
0040870A .8D4D B4 lea ecx,dword ptr ss:
0040870D .50 push eax
0040870E .51 push ecx
0040870F .8D55 C4 lea edx,dword ptr ss:
00408712 .6A 00 push 0x0
00408714 .52 push edx
00408715 .C745 C4 08000>mov dword ptr ss:,0x8
0040871C .FF15 24B14000 call dword ptr ds:[<&MSVBVM50.#595>] ;msvbvm50.rtcMsgBox
爆破就不用说了,直接选中JE语句,右键->Binary->Fill with NOPs. 试一试,OK,爆破成功。
4、注册机的探索:
这个程序和002基本一样的,在跳转附近无任何和Name/Serial相关的内容,所以,向上找到这段代码的开头,下断,一路F8记录重要信息。
PS:由于这个代码太长,只将重要片段拿出来。查找开头时不要急,代码真的很长。需要特别注意和Name/Serial相关的部分。
开头下断位置:004080F0 > \55 push ebp
004080F1 .8BEC mov ebp,esp
004080F3 .83EC 0C sub esp,0xC
004080F6 .68 56104000 push <jmp.&MSVBVM50.__vbaExceptHandler>;SE handler installation
004080FB .64:A1 0000000>mov eax,dword ptr fs:
获取Name的位置:004081E3 .FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;msvbvm50.__vbaHresultCheckObj
004081E9 >8B95 50FFFFFF mov edx,dword ptr ss:
004081EF .8B45 E4 mov eax,dword ptr ss:
004081F2 .50 push eax ;// eax=3333地址
004081F3 .8B1A mov ebx,dword ptr ds:
004081F5 .FF15 F8B04000 call dword ptr ds:[<&MSVBVM50.__vbaLenBs>;msvbvm50.__vbaLenBstr
004081FB .8BF8 mov edi,eax ;// eax=4
004081FD .8B4D E8 mov ecx,dword ptr ss:
00408200 .69FF 385B0100 imul edi,edi,0x15B38 ;// edi=edi*0x15B38
00408206 .51 push ecx
00408207 .0F80 B7050000 jo 004087C4
0040820D .FF15 0CB14000 call dword ptr ds:[<&MSVBVM50.#516>] ;msvbvm50.rtcAnsiValueBstr
00408213 .0FBFD0 movsx edx,ax ;// edx = 第一个字符的ANSI
00408216 .03FA add edi,edx ;// edi=edi+edx
00408218 .0F80 A6050000 jo 004087C4
0040821E .57 push edi
0040821F .FF15 F4B04000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>;msvbvm50.__vbaStrI4
00408225 .8BD0 mov edx,eax ;// eax = 355603 文本
00408227 .8D4D E0 lea ecx,dword ptr ss:
0040822A .FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;msvbvm50.__vbaStrMove
00408230 .8BBD 50FFFFFF mov edi,dword ptr ss:
00408236 .50 push eax ;eax=355603
00408237 .57 push edi ;edi=0091C5B4
00408238 .FF93 A4000000 call dword ptr ds:
0040823E .85C0 test eax,eax ;// eax=0
00408240 .7D 12 jge short 00408254
第一次计算(浮点数):004082D7 .FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;msvbvm50.__vbaHresultCheckObj
004082DD >8B8D 58FFFFFF mov ecx,dword ptr ss:
004082E3 .8B55 E8 mov edx,dword ptr ss:
004082E6 .52 push edx ;// edx=355603
004082E7 .8B19 mov ebx,dword ptr ds:
004082E9 .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;msvbvm50.__vbaR8Str
004082EF .D905 08104000 fld dword ptr ds: ;// 10.0
004082F5 .833D 00904000>cmp dword ptr ds:,0x0
004082FC .75 08 jnz short 00408306
004082FE .D835 0C104000 fdiv dword ptr ds: ;// 5.0, 做除法==2。0
00408304 .EB 0B jmp short 00408311
00408306 >FF35 0C104000 push dword ptr ds:
0040830C .E8 578DFFFF call <jmp.&MSVBVM50._adj_fdiv_m32>
00408311 >83EC 08 sub esp,0x8
00408314 .DFE0 fstsw ax ;// 将值给eax=3100
00408316 .A8 0D test al,0xD
00408318 .0F85 A1040000 jnz 004087BF
0040831E .DEC1 faddp st(1),st ;// 加法,355603 + 2
00408320 .DFE0 fstsw ax
00408322 .A8 0D test al,0xD
00408324 .0F85 95040000 jnz 004087BF
0040832A .DD1C24 fstp qword ptr ss:
0040832D .FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;msvbvm50.__vbaStrR8
00408333 .8BD0 mov edx,eax ;// eax = 355605 字符串
00408335 .8D4D E4 lea ecx,dword ptr ss:
00408338 .FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;msvbvm50.__vbaStrMove
0040833E .899D 34FFFFFF mov dword ptr ss:,ebx
00408344 .8B9D 58FFFFFF mov ebx,dword ptr ss:
0040834A .50 push eax
0040834B .8B85 34FFFFFF mov eax,dword ptr ss: ;// 355605
00408351 .53 push ebx
00408352 .FF90 A4000000 call dword ptr ds:
00408358 .85C0 test eax,eax ;// eax=0,ecx=" "
0040835A .7D 12 jge short 0040836E
第二次计算(浮点数):004083E3 .FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;msvbvm50.__vbaHresultCheckObj
004083E9 >8B8D 58FFFFFF mov ecx,dword ptr ss:
004083EF .8B55 E8 mov edx,dword ptr ss: ;// 355605
004083F2 .52 push edx
004083F3 .8B19 mov ebx,dword ptr ds:
004083F5 .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;msvbvm50.__vbaR8Str
004083FB .DC0D 10104000 fmul qword ptr ds: ;// 355605 * 3 = 1066815.0
00408401 .83EC 08 sub esp,0x8
00408404 .DC25 18104000 fsub qword ptr ds: ;// 1066815 - 2 = 1066813
0040840A .DFE0 fstsw ax ;// ax = 3900
0040840C .A8 0D test al,0xD
0040840E .0F85 AB030000 jnz 004087BF
00408414 .DD1C24 fstp qword ptr ss:
00408417 .FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;msvbvm50.__vbaStrR8
0040841D .8BD0 mov edx,eax ;// eax=1600133
0040841F .8D4D E4 lea ecx,dword ptr ss:
00408422 .FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;msvbvm50.__vbaStrMove
00408428 .899D 2CFFFFFF mov dword ptr ss:,ebx
0040842E .8B9D 58FFFFFF mov ebx,dword ptr ss:
00408434 .50 push eax ;1066813
00408435 .8B85 2CFFFFFF mov eax,dword ptr ss:
0040843B .53 push ebx
0040843C .FF90 A4000000 call dword ptr ds:
00408442 .85C0 test eax,eax
00408444 .7D 12 jge short 00408458
第三次计算(浮点数):004084CD .FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;msvbvm50.__vbaHresultCheckObj
004084D3 >8B8D 58FFFFFF mov ecx,dword ptr ss:
004084D9 .8B55 E8 mov edx,dword ptr ss:
004084DC .52 push edx
004084DD .8B19 mov ebx,dword ptr ds:
004084DF .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;msvbvm50.__vbaR8Str
004084E5 .DC25 20104000 fsub qword ptr ds: ;// 1066813.0 - (-15.0) = 1066828
004084EB .83EC 08 sub esp,0x8
004084EE .DFE0 fstsw ax
004084F0 .A8 0D test al,0xD
004084F2 .0F85 C7020000 jnz 004087BF
004084F8 .DD1C24 fstp qword ptr ss:
004084FB .FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;msvbvm50.__vbaStrR8
00408501 .8BD0 mov edx,eax ;// 1066828
00408503 .8D4D E4 lea ecx,dword ptr ss:
00408506 .FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;msvbvm50.__vbaStrMove
我们的Serial出现了:004085C8 .FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;msvbvm50.__vbaHresultCheckObj
004085CE >8B45 E8 mov eax,dword ptr ss:
004085D1 .50 push eax ;// 获取Serial
004085D2 .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;msvbvm50.__vbaR8Str
004085D8 .8B4D E4 mov ecx,dword ptr ss: ;// 1066828
004085DB .DD9D 1CFFFFFF fstp qword ptr ss:
004085E1 .51 push ecx
004085E2 .FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;msvbvm50.__vbaR8Str
004085E8 .833D 00904000>cmp dword ptr ds:,0x0
004085EF .75 08 jnz short 004085F9
004085F1 .DCBD 1CFFFFFF fdivr qword ptr ss: ;// 做除法
004085F7 .EB 11 jmp short 0040860A
004085F9 > \FFB5 20FFFFFF push dword ptr ss:
004085FF .FFB5 1CFFFFFF push dword ptr ss:
00408605 .E8 888AFFFF call <jmp.&MSVBVM50._adj_fdivr_m64>
0040860A >DFE0 fstsw ax ;// 把结果送入ax
0040860C .A8 0D test al,0xD
0040860E .0F85 AB010000 jnz 004087BF
00408614 .FF15 34B14000 call dword ptr ds:[<&MSVBVM50.__vbaFpR8>>;msvbvm50.__vbaFpR8
0040861A .DC1D 28104000 fcomp qword ptr ds:
00408620 .DFE0 fstsw ax ;//ax=20
00408622 .F6C4 40 test ah,0x40 ;// ah=40
00408625 .74 07 je short 0040862E
后面做的除法运算和取反,为了处理esi的值,然后做为JE的条件。我们到这里其实就可以试试算出来的字符串“1066828”是否是正确的?哈哈,他肯定是的啦!00408665 .66:85F6 test si,si
00408668 .8945 94 mov dword ptr ss:,eax
0040866B .894D AC mov dword ptr ss:,ecx
0040866E .8945 A4 mov dword ptr ss:,eax
00408671 .894D BC mov dword ptr ss:,ecx
00408674 .8945 B4 mov dword ptr ss:,eax
00408677 74 62 je short 004086DB ;// 爆破的关键
00408679 .8B35 14B14000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaSt>;msvbvm50.__vbaStrCat
0040867F .68 C06F4000 push 00406FC0 ;UNICODE "You Get It"
00408684 .68 DC6F4000 push 00406FDC ;ASCII "\r"
00408689 .FFD6 call esi ;<&MSVBVM50.__vbaStrCat>
至此,序列号的生成过程已经分析完毕。过程中设计到的常量都是使用等固定地址得到的固定值,不用理会,我们可以直接使用。
小结一下:先计算出Name的长度nLen,然后edi=edi*0x15B38+cName, cName是Name第一个字符的ANSI码。然后,计算浮点数10.0/5.0=2.0, edi转换为浮点数,加上2.0,然后结果再乘以3.0,然后减去2,然后再减去-15,得到的值转换为文本,即为正确的序列号。
C/CPP代码:// CrackMe160.cpp : 定义控制台应用程序的入口点。
// 003
#include "stdafx.h"
#include <stdio.h>
#include "iostream"
char buff = {0};
int _tmain(int argc, _TCHAR* argv[])
{
printf("160CrackMe-003 Name/Serial\r\n\r\n");
printf("Name:");
gets_s(buff,100);
int nLen = strlen(buff);
if ( nLen > 0 )
{
int nRet = nLen * 0x15B38;
nRet += buff;
double dRet = (double)nRet;
dRet += (10.0/5.0);
dRet *= 3.0;
dRet -= 2;
dRet -= -15;
printf("Serial:%d\r\n",(int)dRet);
}else{
printf("Input error!\r\n");
}
system("pause");
return 0;
}
BY 笨笨D幸福
楼主你好,关于这个程序,我觉得爆破的话还不够完美。
1.打开程序后的等待,能否去除。
2.程序打开后,不输入任何内容点击ok按钮后,弹出错误对话框,能否去除。
3.弹出的错误对话框点击确定后程序自动退出,能否去除。
以上三点是我在爆破这个软件中遇到的阻碍,不会弄,希望能和楼主请教这个问题。诚心请教。 44018723 发表于 2014-11-10 20:20
你这三个问题是一个浩大的工程,对不住啦
其实我最想解决的是第二个问题{:1_926:}。楼主你知道怎么弄吗?一号creak我就搞定了完美爆破,二号我找不到那个错误对话框在哪里呢。你找得到吗? {:17_1065:}报告版主,图片都本地啦!! 学习资料先拿下 强大的资料,拿走了,顺便平分 这个必须有啊 楼主好强大,这个必须顶 高手,膜拜 谢谢楼主, 楼主把第一个帖子加个系列目录吧~~~~~