首页 > 代码库 > [反汇编练习] 160个CrackMe之020
[反汇编练习] 160个CrackMe之020
[反汇编练习] 160个CrackMe之020.
本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。
其中,文章中按照如下逻辑编排(解决如下问题):
1、使用什么环境和工具
2、程序分析
3、思路分析和破解流程
4、注册机的探索
----------------------------------
提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大,只要你跟踪了,不用怎么看代码就理解了!
----------------------------------
1、工具和环境:
WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。
160个CrackMe的打包文件。
下载地址: http://pan.baidu.com/s/1xUWOY 密码: jbnq
注:
1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。
2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。
2、程序分析:
想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。
和上一节一样,打开CHM,选择第20个BuLLeT.8.exe,保存下来。运行程序,程序界面如下:
输入错误信息无任何反应!
3、思路分析和破解流程
PEID查壳:WWPack32 1.x -> Piotr Warezak
网上搜索,大家都说是比较简单的,但是针对我这样的小白,还是很难啊!
这个壳有很多脱壳工具都可以脱,包括文章开头提供的PEID里面有一个插件“通用脱壳机”也可以脱掉。
(其实我就是先使用“通用OEP查找工具”看完才试着手动脱的。)
手工脱壳总共就两种办法:
1、ESP定律在这里无法使用(可能OD设置有问题)
2、手动单步跟踪。
全程F8,遇到需要跳过的在下一句F2断点,然后F9。(因为这个OD使用“运行到此处”功能程序会直接退出,很无语...)
最后的跳转地方:
00465247 8A13 mov dl,byte ptr ds:[ebx]00465249 43 inc ebx0046524A 80FA 00 cmp dl,0x00046524D ^ 74 E8 je short 004652370046524F 03F2 add esi,edx00465251 ^ EB F0 jmp short 0046524300465253 58 pop eax00465254 2E:0385 6302000>add eax,dword ptr cs:[ebp+0x263]0046525B 05 67020000 add eax,0x26700465260 5D pop ebp00465261 5B pop ebx00465262 - E9 E153FEFF jmp 0044A648 ; // 入口,先进去下断,再运行0044A648 55 push ebp ; 先在这里设置F2断点,然后再运行到这里0044A649 8BEC mov ebp,esp0044A64B 83C4 F4 add esp,-0xC0044A64E B8 78A44400 mov eax,0044A478 ; UNICODE "9"0044A653 E8 14B8FBFF call 00405E6C ; 在这里下断会发现eax="MZP",呵呵0044A658 A1 84BD4400 mov eax,dword ptr ds:[0x44BD84]0044A65D 8B00 mov eax,dword ptr ds:[eax]0044A65F E8 CC5BFFFF call 004402300044A664 8B0D 58BE4400 mov ecx,dword ptr ds:[0x44BE58] ; BuLLeT_8.0044C8C80044A66A A1 84BD4400 mov eax,dword ptr ds:[0x44BD84]0044A66F 8B00 mov eax,dword ptr ds:[eax]0044A671 8B15 68A04400 mov edx,dword ptr ds:[0x44A068] ; BuLLeT_8.0044A0B40044A677 E8 CC5BFFFF call 004402480044A67C 8B0D 80BE4400 mov ecx,dword ptr ds:[0x44BE80] ; BuLLeT_8.0044C8C00044A682 A1 84BD4400 mov eax,dword ptr ds:[0x44BD84]0044A687 8B00 mov eax,dword ptr ds:[eax]0044A689 8B15 E89E4400 mov edx,dword ptr ds:[0x449EE8] ; BuLLeT_8.00449F340044A68F E8 B45BFFFF call 004402480044A694 A1 84BD4400 mov eax,dword ptr ds:[0x44BD84]0044A699 8B00 mov eax,dword ptr ds:[eax]0044A69B E8 285CFFFF call 004402C80044A6A0 E8 0390FBFF call 004036A80044A6A5 8D40 00 lea eax,dword ptr ds:[eax]0044A6A8 C740 0D 9CFCC34>mov dword ptr ds:[eax+0xD],0x41C3FC9C0044A6AF 1E push ds0044A6B0 27 daa0044A6B1 CB retf
选中头部,右键->使用Ollydump脱壳调试程序,点击“脱壳”,然后将脱壳后程序保存。
将保存后的程序运行,OK,没问题!(其实,换个系统就有问题了,暂时不管他)
假设脱壳后的程序另存为unPack.exe,使用PEID查看,发现是Borland Delphi 4.0 - 5.0的,先使用IDR分析一下。
窗口内容:(发现右侧有一个奖杯的图片,正常的不显示)
查看按钮事件:
Unit1::TForm1.Button1Click 0044A2E8 push ebp 0044A2E9 mov ebp,esp 0044A2EB xor ecx,ecx 0044A2ED push ecx 0044A2EE push ecx 0044A2EF push ecx 0044A2F0 push ecx 0044A2F1 push ebx 0044A2F2 push esi 0044A2F3 mov ebx,eax 0044A2F5 xor eax,eax 0044A2F7 push ebp 0044A2F8 push 44A3E4 0044A2FD push dword ptr fs:[eax] 0044A300 mov dword ptr fs:[eax],esp 0044A303 lea edx,[ebp-4] 0044A306 mov eax,dword ptr [ebx+2C8]; TForm1.Edit2:TEdit 0044A30C call TControl.GetText 0044A311 mov eax,dword ptr [ebp-4] 0044A314 call StrToInt 0044A319 mov esi,eax 0044A31B mov eax,dword ptr [ebp-4] 0044A31E call StrToInt64 0044A323 push edx 0044A324 push eax 0044A325 mov eax,esi 0044A327 cdq 0044A328 add eax,dword ptr [esp] 0044A32B adc edx,dword ptr [esp+4] 0044A32F add esp,8 0044A332 push edx 0044A333 push eax 0044A334 mov eax,esi 0044A336 cdq 0044A337 add eax,dword ptr [esp] 0044A33A adc edx,dword ptr [esp+4] 0044A33E add esp,8 0044A341 push edx 0044A342 push eax 0044A343 lea edx,[ebp-8] 0044A346 mov eax,6 0044A34B call IntToHex 0044A350 mov edx,dword ptr [ebp-8] 0044A353 mov eax,dword ptr [ebx+2CC]; TForm1.Edit3:TEdit 0044A359 call TControl.SetText 0044A35E lea edx,[ebp-0C] 0044A361 mov eax,dword ptr [ebx+2CC]; TForm1.Edit3:TEdit 0044A367 call TControl.GetText 0044A36C mov eax,dword ptr [ebp-0C] 0044A36F push eax 0044A370 lea edx,[ebp-10] 0044A373 mov eax,dword ptr [ebx+2F0]; TForm1.Label1:TLabel 0044A379 call TControl.GetText 0044A37E mov edx,dword ptr [ebp-10] 0044A381 pop eax 0044A382 call @LStrCmp>0044A387 jne 0044A398 0044A389 mov dl,1 0044A38B mov eax,dword ptr [ebx+2FC]; TForm1.Label2:TLabel 0044A391 call TControl.SetVisible>0044A396 jmp 0044A3A9 0044A398 mov eax,dword ptr [ebx+2D4]; TForm1.Label6:TLabel 0044A39E mov edx,dword ptr [eax+34]; TLabel.Top:Integer 0044A3A1 sub edx,0A 0044A3A4 call TControl.SetTop 0044A3A9 mov eax,dword ptr [ebx+2D4]; TForm1.Label6:TLabel 0044A3AF cmp dword ptr [eax+34],32; TLabel.Top:Integer>0044A3B3 jge 0044A3BC 0044A3B5 mov eax,ebx 0044A3B7 call TCustomForm.Close 0044A3BC xor eax,eax 0044A3BE pop edx 0044A3BF pop ecx 0044A3C0 pop ecx 0044A3C1 mov dword ptr fs:[eax],edx 0044A3C4 push 44A3EB 0044A3C9 lea eax,[ebp-10] 0044A3CC mov edx,2 0044A3D1 call @LStrArrayClr 0044A3D6 lea eax,[ebp-8] 0044A3D9 mov edx,2 0044A3DE call @LStrArrayClr 0044A3E3 ret<0044A3E4 jmp @HandleFinally<0044A3E9 jmp 0044A3C9 0044A3EB pop esi 0044A3EC pop ebx 0044A3ED mov esp,ebp 0044A3EF pop ebp 0044A3F0 ret
根据函数的名称,我们很容易找到了关键的Call和跳转:
0044A382 call @LStrCmp
>0044A387 jne 0044A398
我们尝试在OD中将jne 0044A398使用NOP填充,然后再换到exe中,点击按钮,发现:
哈哈,爆破成功的!!
4、注册机的探索
参考IDR的分析结果,在OD中从头开始跟踪对应地址,F8单步分析:
0044A2E8 /. 55 push ebp ; // Splder按钮点击事件0044A2E9 |. 8BEC mov ebp,esp0044A2EB |. 33C9 xor ecx,ecx0044A2ED |. 51 push ecx0044A2EE |. 51 push ecx0044A2EF |. 51 push ecx0044A2F0 |. 51 push ecx0044A2F1 |. 53 push ebx0044A2F2 |. 56 push esi0044A2F3 |. 8BD8 mov ebx,eax0044A2F5 |. 33C0 xor eax,eax0044A2F7 |. 55 push ebp0044A2F8 |. 68 E4A34400 push 0044A3E40044A2FD |. 64:FF30 push dword ptr fs:[eax]0044A300 |. 64:8920 mov dword ptr fs:[eax],esp0044A303 |. 8D55 FC lea edx,[local.1]0044A306 |. 8B83 C8020000 mov eax,dword ptr ds:[ebx+0x2C8] ; TForm1.Edit2:TEdit0044A30C |. E8 FBA0FDFF call 0042440C ; TControl.GetText0044A311 |. 8B45 FC mov eax,[local.1] ; // eax = "12345"0044A314 |. E8 EFD6FBFF call 00407A08 ; StrToInt0044A319 |. 8BF0 mov esi,eax ; // eax = 0x00003039 = 123450044A31B |. 8B45 FC mov eax,[local.1]0044A31E |. E8 5DD7FBFF call 00407A80 ; StrToInt640044A323 |. 52 push edx ; // edx = 00044A324 |. 50 push eax ; // eax = 0x00003039 = 123450044A325 |. 8BC6 mov eax,esi ; // esi = eax (64位)0044A327 |. 99 cdq ; // edx 扩展为eax的最高位,// edx = 00044A328 |. 030424 add eax,dword ptr ss:[esp] ; // [esp] = 0x3039 = 123450044A32B |. 135424 04 adc edx,dword ptr ss:[esp+0x4] ; // 带进位加法指令,00044A32F |. 83C4 08 add esp,0x80044A332 |. 52 push edx0044A333 |. 50 push eax0044A334 |. 8BC6 mov eax,esi ; // esi = 123450044A336 |. 99 cdq0044A337 |. 030424 add eax,dword ptr ss:[esp] ; // [esp] = 0x6072, eax = 000090AB0044A33A |. 135424 04 adc edx,dword ptr ss:[esp+0x4]0044A33E |. 83C4 08 add esp,0x80044A341 |. 52 push edx ; /Arg2 = 00044A342 |. 50 push eax ; |Arg1 = 0x000090AB = 370350044A343 |. 8D55 F8 lea edx,[local.2] ; |0044A346 |. B8 06000000 mov eax,0x6 ; |0044A34B |. E8 78D6FBFF call 004079C8 ; \IntToHex0044A350 |. 8B55 F8 mov edx,[local.2]0044A353 |. 8B83 CC020000 mov eax,dword ptr ds:[ebx+0x2CC] ; TForm1.Edit3:TEdit0044A359 |. E8 DEA0FDFF call 0042443C ; TControl.SetText0044A35E |. 8D55 F4 lea edx,[local.3]0044A361 |. 8B83 CC020000 mov eax,dword ptr ds:[ebx+0x2CC] ; TForm1.Edit3:TEdit0044A367 |. E8 A0A0FDFF call 0042440C ; TControl.GetText0044A36C |. 8B45 F4 mov eax,[local.3]0044A36F |. 50 push eax0044A370 |. 8D55 F0 lea edx,[local.4]0044A373 |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0] ; TForm1.Label1:TLabel0044A379 |. E8 8EA0FDFF call 0042440C ; TControl.GetText0044A37E |. 8B55 F0 mov edx,[local.4]0044A381 |. 58 pop eax0044A382 |. E8 6198FBFF call 00403BE8 ; @LStrCmp // 进行文本比较0044A387 75 0F jnz short 0044A398 ; // 关键跳转0044A389 |. B2 01 mov dl,0x10044A38B |. 8B83 FC020000 mov eax,dword ptr ds:[ebx+0x2FC] ; TForm1.Label2:TLabel0044A391 |. E8 669FFDFF call 004242FC ; TControl.SetVisible0044A396 |. EB 11 jmp short 0044A3A90044A398 |> 8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4] ; TForm1.Label6:TLabel0044A39E |. 8B50 34 mov edx,dword ptr ds:[eax+0x34] ; TLabel.Top:Integer0044A3A1 |. 83EA 0A sub edx,0xA0044A3A4 |. E8 4398FDFF call 00423BEC ; TControl.SetTop0044A3A9 |> 8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4] ; TForm1.Label6:TLabel0044A3AF |. 8378 34 32 cmp dword ptr ds:[eax+0x34],0x32 ; TLabel.Top:Integer0044A3B3 |. 7D 07 jge short 0044A3BC0044A3B5 |. 8BC3 mov eax,ebx0044A3B7 |. E8 302EFFFF call 0043D1EC ; TCustomForm.Close0044A3BC |> 33C0 xor eax,eax0044A3BE |. 5A pop edx0044A3BF |. 59 pop ecx0044A3C0 |. 59 pop ecx0044A3C1 |. 64:8910 mov dword ptr fs:[eax],edx0044A3C4 |. 68 EBA34400 push 0044A3EB0044A3C9 |> 8D45 F0 lea eax,[local.4]0044A3CC |. BA 02000000 mov edx,0x20044A3D1 |. E8 AA94FBFF call 00403880 ; @LStrArrayClr0044A3D6 |. 8D45 F8 lea eax,[local.2]0044A3D9 |. BA 02000000 mov edx,0x20044A3DE |. E8 9D94FBFF call 00403880 ; @LStrArrayClr0044A3E3 \. C3 retn
总结:算法的核心部分在0044A336 地址处,他其实就是将我们输入的key乘以3,然后将结果的HEX值与显示出来的3E74984B 比较,相等则认为是正确的。
所以注册码很简单,就是3E74984B 转换为10进制,除上3得到的整数值。即3E74984B = 1047828555/3 = 349276185。
BY 笨笨D幸福