首页
社区
课程
招聘
[原创]D4ph1 - Crackme#1分析
发表于: 2005-11-25 10:47 6189

[原创]D4ph1 - Crackme#1分析

2005-11-25 10:47
6189

    最近在突然在好几个群里看到要求分析D4ph1 - Crackme#1的BBS,拿来看了一下,觉得比较另类,所以贴了篇文章放这里。
软件下载地址:http://www.crackmes.de/users/d4ph1/d4ph1_crackme1

分析过程:

0040110E           6A 40           push 40
00401110           6A 0D           push 0D
00401112           68 EA030000     push 3EA
00401117           FF75 08         push dword ptr ss:[ebp+8]
0040111A           E8 8D010000     call <jmp.&user32.SendDlgItemMessag>; 取用户名长度
0040111F           A2 0D344000     mov byte ptr ds:[40340D],al        00401124           3C 04           cmp al,4                            ; 是否大于4位
00401126           0F86 21010000   jbe D4ph1_-_.0040124D               ; 小于则跳到下面的用户名出错信息
0040112C           3C 06           cmp al,6                            ; 是否等于6位
0040112E           75 07           jnz short D4ph1_-_.00401137         ; 不等就跳到401137处
00401130           C605 0C344000 0>mov byte ptr ds:[40340C],1
00401137           8BD0            mov edx,eax                         ; 用户名长度放入EDX中
00401139           33DB            xor ebx,ebx                         ; EBX清0
0040113B           33F6            xor esi,esi                         ; ESI清零
0040113D           8A86 4C334000   mov al,byte ptr ds:[esi+40334C]     ; 逐个取用户名的十六进制码(开始循环)
00401143           3086 80324000   xor byte ptr ds:[esi+403280],al     ;
00401149           33DB            xor ebx,ebx                         ; EBX清零
0040114B           03D8            add ebx,eax                         ; EBX=EBX+EAX(EAX中放着用户名的十六进制码)
0040114D           33DA            xor ebx,edx                         ; EDX=用户名位数,EBX做异或运算0040114F           899E 8C334000   mov dword ptr ds:[esi+40338C],ebx   ; 结果放入ESI+40338C中保存
00401155           46              inc esi                             ; 取用户名下一位
00401156           4A              dec edx                             ; edx=edx-1,用户名位数减1,直到取完
00401157         ^ 75 E4           jnz short D4ph1_-_.0040113D         ; 没有取完则继续循环
00401159           C686 8C334000 2>mov byte ptr ds:[esi+40338C],2D     ; ESI+40338C中存放着最终的用户名计算结果
00401160           68 CC334000     push D4ph1_-_.004033CC
00401165           6A 41           push 41
00401167           6A 0D           push 0D
00401169           68 EB030000     push 3EB
0040116E           FF75 08         push dword ptr ss:[ebp+8]
00401171           E8 36010000     call <jmp.&user32.SendDlgItemMessag>; 取注册码
00401176           33D2            xor edx,edx                         ; EDX清零
00401178           0FBEBA CC334000 movsx edi,byte ptr ds:[edx+4033CC]  ; 逐个取注册码码的十六进制码放入EDI
0040117F           0FBE9A 8C334000 movsx ebx,byte ptr ds:[edx+40338C]  ; 看上面,40338C中放的是用户名的计算结果,放回EDX
00401186           42              inc edx                             ; EDX=EDX+1,计数器,逐个取
00401187           3BFB            cmp edi,ebx                         ; 用户名的计算结果与注册码的十六进制码逐个对比(关键)
00401189         ^ 74 ED           je short D4ph1_-_.00401178          ; 相等就跳到401178继续循环。(不等难道不行?往下看)
0040118B           4A              dec edx                             ; 注册码字符长度减1
0040118C           83F2 45         xor edx,45                          ; 注册码长度与45做异或运算,放入EDX
0040118F           83F6 45         xor esi,45                          ; ESI放的是用户名长度,与45做异或运算,放入ESI
00401192           2BD6            sub edx,esi                         ; EDX=EDX-ESI
00401194           75 6A           jnz short D4ph1_-_.00401200         ; 不等就跳到401200处还有秘密的NAG----爆破点1,改为JE
00401196           E8 97FEFFFF     call D4ph1_-_.00401032                 ; 这个CALL很有意思,是We need his first-name的提示
0040119B           803D 0C344000 0>cmp byte ptr ds:[40340C],1
004011A2           75 47           jnz short D4ph1_-_.004011EB
004011A4           BB 47000000     mov ebx,47                          ; EBX赋值47
004011A9           0FBEBA CC334000 movsx edi,byte ptr ds:[edx+4033CC]  ; 注册码的十六进制码放入EDI
004011B0           0FBEB2 3B334000 movsx esi,byte ptr ds:[edx+40333B]  ; 逐个放入ESI
004011B7           03DE            add ebx,esi                         ; EBX=EBX+ESI
004011B9           3BFB            cmp edi,ebx                         ; EBX的值与EDI对比(注册码的十六进制码与计算结果比较一定要相等,也就是说注册码的第一位必须为47=G,其它的按照上面的规律算)
004011BB           75 2E           jnz short D4ph1_-_.004011EB         ; 不等就跳到4011EB处----爆破点2,NOP掉
004011BD           42              inc edx                             ; 相等的话继续取下一个
004011BE           83FA 05         cmp edx,5                           ; 取剩的位数与5比较
004011C1         ^ 76 E6           jbe short D4ph1_-_.004011A9         ; 小于等于就循环
004011C3           6A 00           push 0
004011C5           68 00304000     push D4ph1_-_.00403000              ; ASCII "Crackme#1 By D4ph1"
004011CA           68 80324000     push D4ph1_-_.00403280
004011CF           6A 00           push 0
004011D1           E8 CA000000     call <jmp.&user32.MessageBoxA>      ; 爆破点3--NOP掉去NAG
004011D6           6A 00           push 0
004011D8           68 00304000     push D4ph1_-_.00403000              ; ASCII "Crackme#1 By D4ph1"
004011DD           68 13304000     push D4ph1_-_.00403013              ; ASCII "Great work mate!You passed all the tests!:)"

算法总结:用户名取六位,与注册码长度相等,用户名的十六进制码与该注册码的倒数位置做异或运算,得出的结果要与注册码的十六进制码相等,程序对注册码做了规定,前六位必须为Giffpu,相应的用户名为Albert。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 560
活跃值: (359)
能力值: ( LV13,RANK:1370 )
在线值:
发帖
回帖
粉丝
2
用户名必须为6位,取每个用户名ASCII的十六进制码与它所处的倒数位置做异或运算后组成注册码。程序最后规定了注册码必须为Giffpu,补上推算用户名的VB注册机源码:

Private Sub Command1_Click()
Dim yhm As String
zcm = Text1.Text
If Len(ZCM) <> 6 Or Len(ZCM) <> Giffpu Then
    MsgBox "^0^哈哈,注册码是固定的:Giffpu ^0^", , "提示"
Else
For i = 1 To 6
    yhm = yhm + Chr(Asc(Mid(zcm, i, 1)) Xor (7 - i))
Next i
     Text2.Text = yhm
End If
End Sub

VB6,WINXP SP2下编译通过。
上传的附件:
2006-4-11 13:23
0
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
文章不错。如果方便希望将CrackMe转份本地。
2006-4-11 13:43
0
游客
登录 | 注册 方可回帖
返回
//