[反汇编练习] 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使用“运行到此处”功能程序会直接退出,很无语...) 最后的跳转地方:
[Asm] 纯文本查看 复制代码 00465247 8A13 mov dl,byte ptr ds:[ebx]
00465249 43 inc ebx
0046524A 80FA 00 cmp dl,0x0
0046524D ^ 74 E8 je short 00465237
0046524F 03F2 add esi,edx
00465251 ^ EB F0 jmp short 00465243
00465253 58 pop eax
00465254 2E:0385 6302000>add eax,dword ptr cs:[ebp+0x263]
0046525B 05 67020000 add eax,0x267
00465260 5D pop ebp
00465261 5B pop ebx
00465262 - E9 E153FEFF jmp 0044A648 ; // 入口,先进去下断,再运行
0044A648 55 push ebp ; 先在这里设置F2断点,然后再运行到这里
0044A649 8BEC mov ebp,esp
0044A64B 83C4 F4 add esp,-0xC
0044A64E 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 00440230
0044A664 8B0D 58BE4400 mov ecx,dword ptr ds:[0x44BE58] ; BuLLeT_8.0044C8C8
0044A66A 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.0044A0B4
0044A677 E8 CC5BFFFF call 00440248
0044A67C 8B0D 80BE4400 mov ecx,dword ptr ds:[0x44BE80] ; BuLLeT_8.0044C8C0
0044A682 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.00449F34
0044A68F E8 B45BFFFF call 00440248
0044A694 A1 84BD4400 mov eax,dword ptr ds:[0x44BD84]
0044A699 8B00 mov eax,dword ptr ds:[eax]
0044A69B E8 285CFFFF call 004402C8
0044A6A0 E8 0390FBFF call 004036A8
0044A6A5 8D40 00 lea eax,dword ptr ds:[eax]
0044A6A8 C740 0D 9CFCC34>mov dword ptr ds:[eax+0xD],0x41C3FC9C
0044A6AF 1E push ds
0044A6B0 27 daa
0044A6B1 CB retf
选中头部,右键->使用Ollydump脱壳调试程序,点击“脱壳”,然后将脱壳后程序保存。 将保存后的程序运行,OK,没问题!(其实,换个系统就有问题了,暂时不管他)
假设脱壳后的程序另存为unPack.exe,使用PEID查看,发现是Borland Delphi 4.0 - 5.0的,先使用IDR分析一下。 窗口内容:(发现右侧有一个奖杯的图片,正常的不显示) 查看按钮事件:
[Asm] 纯文本查看 复制代码 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单步分析:
[Asm] 纯文本查看 复制代码 0044A2E8 /. 55 push ebp ; // Splder按钮点击事件
0044A2E9 |. 8BEC mov ebp,esp
0044A2EB |. 33C9 xor ecx,ecx
0044A2ED |. 51 push ecx
0044A2EE |. 51 push ecx
0044A2EF |. 51 push ecx
0044A2F0 |. 51 push ecx
0044A2F1 |. 53 push ebx
0044A2F2 |. 56 push esi
0044A2F3 |. 8BD8 mov ebx,eax
0044A2F5 |. 33C0 xor eax,eax
0044A2F7 |. 55 push ebp
0044A2F8 |. 68 E4A34400 push 0044A3E4
0044A2FD |. 64:FF30 push dword ptr fs:[eax]
0044A300 |. 64:8920 mov dword ptr fs:[eax],esp
0044A303 |. 8D55 FC lea edx,[local.1]
0044A306 |. 8B83 C8020000 mov eax,dword ptr ds:[ebx+0x2C8] ; TForm1.Edit2:TEdit
0044A30C |. E8 FBA0FDFF call 0042440C ; TControl.GetText
0044A311 |. 8B45 FC mov eax,[local.1] ; // eax = "12345"
0044A314 |. E8 EFD6FBFF call 00407A08 ; StrToInt
0044A319 |. 8BF0 mov esi,eax ; // eax = 0x00003039 = 12345
0044A31B |. 8B45 FC mov eax,[local.1]
0044A31E |. E8 5DD7FBFF call 00407A80 ; StrToInt64
0044A323 |. 52 push edx ; // edx = 0
0044A324 |. 50 push eax ; // eax = 0x00003039 = 12345
0044A325 |. 8BC6 mov eax,esi ; // esi = eax (64位)
0044A327 |. 99 cdq ; // edx 扩展为eax的最高位,// edx = 0
0044A328 |. 030424 add eax,dword ptr ss:[esp] ; // [esp] = 0x3039 = 12345
0044A32B |. 135424 04 adc edx,dword ptr ss:[esp+0x4] ; // 带进位加法指令,0
0044A32F |. 83C4 08 add esp,0x8
0044A332 |. 52 push edx
0044A333 |. 50 push eax
0044A334 |. 8BC6 mov eax,esi ; // esi = 12345
0044A336 |. 99 cdq
0044A337 |. 030424 add eax,dword ptr ss:[esp] ; // [esp] = 0x6072, eax = 000090AB
0044A33A |. 135424 04 adc edx,dword ptr ss:[esp+0x4]
0044A33E |. 83C4 08 add esp,0x8
0044A341 |. 52 push edx ; /Arg2 = 0
0044A342 |. 50 push eax ; |Arg1 = 0x000090AB = 37035
0044A343 |. 8D55 F8 lea edx,[local.2] ; |
0044A346 |. B8 06000000 mov eax,0x6 ; |
0044A34B |. E8 78D6FBFF call 004079C8 ; \IntToHex
0044A350 |. 8B55 F8 mov edx,[local.2]
0044A353 |. 8B83 CC020000 mov eax,dword ptr ds:[ebx+0x2CC] ; TForm1.Edit3:TEdit
0044A359 |. E8 DEA0FDFF call 0042443C ; TControl.SetText
0044A35E |. 8D55 F4 lea edx,[local.3]
0044A361 |. 8B83 CC020000 mov eax,dword ptr ds:[ebx+0x2CC] ; TForm1.Edit3:TEdit
0044A367 |. E8 A0A0FDFF call 0042440C ; TControl.GetText
0044A36C |. 8B45 F4 mov eax,[local.3]
0044A36F |. 50 push eax
0044A370 |. 8D55 F0 lea edx,[local.4]
0044A373 |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0] ; TForm1.Label1:TLabel
0044A379 |. E8 8EA0FDFF call 0042440C ; TControl.GetText
0044A37E |. 8B55 F0 mov edx,[local.4]
0044A381 |. 58 pop eax
0044A382 |. E8 6198FBFF call 00403BE8 ; @LStrCmp // 进行文本比较
0044A387 75 0F jnz short 0044A398 ; // 关键跳转
0044A389 |. B2 01 mov dl,0x1
0044A38B |. 8B83 FC020000 mov eax,dword ptr ds:[ebx+0x2FC] ; TForm1.Label2:TLabel
0044A391 |. E8 669FFDFF call 004242FC ; TControl.SetVisible
0044A396 |. EB 11 jmp short 0044A3A9
0044A398 |> 8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4] ; TForm1.Label6:TLabel
0044A39E |. 8B50 34 mov edx,dword ptr ds:[eax+0x34] ; TLabel.Top:Integer
0044A3A1 |. 83EA 0A sub edx,0xA
0044A3A4 |. E8 4398FDFF call 00423BEC ; TControl.SetTop
0044A3A9 |> 8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4] ; TForm1.Label6:TLabel
0044A3AF |. 8378 34 32 cmp dword ptr ds:[eax+0x34],0x32 ; TLabel.Top:Integer
0044A3B3 |. 7D 07 jge short 0044A3BC
0044A3B5 |. 8BC3 mov eax,ebx
0044A3B7 |. E8 302EFFFF call 0043D1EC ; TCustomForm.Close
0044A3BC |> 33C0 xor eax,eax
0044A3BE |. 5A pop edx
0044A3BF |. 59 pop ecx
0044A3C0 |. 59 pop ecx
0044A3C1 |. 64:8910 mov dword ptr fs:[eax],edx
0044A3C4 |. 68 EBA34400 push 0044A3EB
0044A3C9 |> 8D45 F0 lea eax,[local.4]
0044A3CC |. BA 02000000 mov edx,0x2
0044A3D1 |. E8 AA94FBFF call 00403880 ; @LStrArrayClr
0044A3D6 |. 8D45 F8 lea eax,[local.2]
0044A3D9 |. BA 02000000 mov edx,0x2
0044A3DE |. E8 9D94FBFF call 00403880 ; @LStrArrayClr
0044A3E3 \. C3 retn
总结:算法的核心部分在0044A336 地址处,他其实就是将我们输入的key乘以3,然后将结果的HEX值与显示出来的3E74984B 比较,相等则认为是正确的。 所以注册码很简单,就是3E74984B 转换为10进制,除上3得到的整数值。即3E74984B = 1047828555/3 = 349276185。
BY 笨笨D幸福
|