首页
社区
课程
招聘
Knight's Crackme#1算法分析
发表于: 2006-7-23 12:21 8052

Knight's Crackme#1算法分析

2006-7-23 12:21
8052

【破文标题】Knight's Crackme#1破解分析
【破文作者】逍遥风
【破解工具】OD 计算器
【破解平台】WINXP
【软件名称】Knight's Crackme#1
【软件大小】14K
【原版下载】http://www.crackmes.de/users/knight/knights_crackme1/
【保护方式】UPX
【软件简介】My first crackme :)
Don't know what to say more. Get it and see everything on your own."

Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows
Language: C/C++

----------------------------------------------------------------------
很简单的UPX壳,脱壳后再用0D载入
任意输入注册信息
注册名:lovetc
注册码:1234567
断点很好下就不多说了
----------------------------------------------------------------------
根据错误提示来到这里:
0040111C    FF15 B0504000   call    dword ptr [<&USER32.GetWindowT>; 取注册名位数。
00401122    BB F3030000     mov     ebx, 3F3                       
00401127    8945 FC         mov     dword ptr [ebp-4], eax         ; 储存注册名的位数
0040112A    53              push    ebx
0040112B    FF75 08         push    dword ptr [ebp+8]
0040112E    FFD6            call    esi
00401130    50              push    eax
00401131    FF15 B0504000   call    dword ptr [<&USER32.GetWindowT>; 取输入的注册码的位数
00401137    8BF0            mov     esi, eax                       ; 使ESI=EAX,即保存输入的注册码的位数
00401139    8B45 FC         mov     eax, dword ptr [ebp-4]         ; 使EAX等于注册名的位数
0040113C    85C0            test    eax, eax                       ; 检验是否输入了注册名
0040113E    0F84 26010000   je      0040126A                       ; 没有输入注册名就跳向失败
00401144    85F6            test    esi, esi                       ; 检验是否输入了注册码
00401146    0F84 1E010000   je      0040126A                       ; 没有输入注册码就跳向失败
0040114C    83F8 05         cmp     eax, 5                         ; 注册名位数与5比较
0040114F    7D 11           jge     short 00401162                 ; 注册名小于5位就出现错误提示
----------------------------------------------------------------------
004011A6    56              push    esi                            ; 来到这里
004011A7    E8 E4010000     call    00401390                       ; 对注册码格式的处理(跟进)
004011AC    84C0            test    al, al
004011AE    0F84 8F000000   je      00401243
004011B4    8066 04 00      and     byte ptr [esi+4], 0
004011B8    8066 09 00      and     byte ptr [esi+9], 0
----------------------------------------------------------------------跟进“对注册码格式的处理”的那个CALL
004013B4    8B7D 08         mov     edi, dword ptr [ebp+8]         ; 取出输入的注册码
004013B7    0FB647 04       movzx   eax, byte ptr [edi+4]          ; 取输入的注册码的第5位
004013BB    F6D0            not     al
004013BD    C1E0 04         shl     eax, 4
004013C0    0AC4            or      al, ah
004013C2    3A47 09         cmp     al, byte ptr [edi+9]           ; 检查注册码的第5位和第10位是否相等
004013C5    75 4A           jnz     short 00401411
004013C7    0FB647 09       movzx   eax, byte ptr [edi+9]          ; 取注册码的第10位
004013CB    F6D0            not     al
004013CD    C1E0 04         shl     eax, 4
004013D0    0AC4            or      al, ah
004013D2    3A47 04         cmp     al, byte ptr [edi+4]           ; 检查注册码的第5位和第10位是否相等
004013D5    75 3A           jnz     short 00401411
004013D7    B9 03000000     mov     ecx, 3                         ; 使ECX等于3
004013DC    8B75 08         mov     esi, dword ptr [ebp+8]         ; 使ESI等于输入的注册码
004013DF    33DB            xor     ebx, ebx                       ; EBX清零
004013E1    BA 04000000     mov     edx, 4                         ; 使EDX等于4
004013E6    8A06            mov     al, byte ptr [esi]             ; 取注册码的第一位
004013E8    3C 30           cmp     al, 30
004013EA    7C 25           jl      short 00401411
004013EC    3C 46           cmp     al, 46
004013EE    7F 21           jg      short 00401411
004013F0    3C 39           cmp     al, 39
004013F2    7E 04           jle     short 004013F8
004013F4    3C 41           cmp     al, 41
004013F6    7C 19           jl      short 00401411
004013F8    46              inc     esi                            ; 每计算一次ESI+1(即取下一位)
004013F9    4A              dec     edx                            ; 每计算一次EDX-1
004013FA  ^ 75 EA           jnz     short 004013E6                 ; 循环计算
004013FC    021E            add     bl, byte ptr [esi]             ; 注册码的第10位和第5位相加
004013FE    46              inc     esi
004013FF  ^ E2 E0           loopd   short 004013E1
00401401    83C3 24         add     ebx, 24
00401404    81CB 81000000   or      ebx, 81
0040140A    FEC3            inc     bl
0040140C    0F94C0          sete    al
0040140F    EB 02           jmp     short 00401413
00401411    33C0            xor     eax, eax
00401413    8945 FC         mov     dword ptr [ebp-4], eax
00401416    61              popad
00401417    8B45 FC         mov     eax, dword ptr [ebp-4]
0040141A    C9              leave
0040141B    C2 0400         retn    4
从这段代码可以得知:注册码必须为14位,第5位和第10位必须是“-”
所以:将注册码改为1234-5678-6789。
---------------------------------------------------------------------通过了格式验证后来到这里:
004011BC    56              push    esi
004011BD    E8 10FFFFFF     call    004010D2                       ; 取注册码的第一部分
004011C2    8BF8            mov     edi, eax                       ; 使EDI等于注册码的第一部分(前四位)
004011C4    8D46 05         lea     eax, dword ptr [esi+5]         ; 使EAX等于注册码的第2部分(中间四位)
004011C7    50              push    eax
004011C8    897D E8         mov     dword ptr [ebp-18], edi        ; 储存注册码的第1部分
004011CB    E8 02FFFFFF     call    004010D2                       ; 取注册码的第二部分
004011D0    8BD8            mov     ebx, eax                       ; 使EBX等于注册码的第2部分
004011D2    8D46 0A         lea     eax, dword ptr [esi+A]         ; 使EAX等于注册码的第3部分(最后四位)
004011D5    50              push    eax
004011D6    895D EC         mov     dword ptr [ebp-14], ebx        ; 储存注册码的第2部分
004011D9    E8 F4FEFFFF     call    004010D2                       ; 取注册码的第三部分
004011DE    B9 00100000     mov     ecx, 1000                      ; 使ECX等于0x1000
004011E3    83C4 0C         add     esp, 0C
004011E6    3BF9            cmp     edi, ecx                       ; 注册码的前4位与0x1000相比较
004011E8    8945 F0         mov     dword ptr [ebp-10], eax        ; 储存注册码的第3部分
004011EB    7C 56           jl      short 00401243                 ; 注册码的第一部分要大于1000
004011ED    3BD9            cmp     ebx, ecx                       ; 比较注册码的第2部分
004011EF    7C 52           jl      short 00401243                 ; 注册码的第二部分要大于1000
004011F1    3BC1            cmp     eax, ecx                       ; 比较注册码的第3部分
004011F3    7C 4E           jl      short 00401243                 ; 注册码的第三部分要大于1000
004011F5    3BFB            cmp     edi, ebx                       ; 注册码的第一部分与第二部分比较
004011F7    7E 4A           jle     short 00401243                 ; 注册码的第1部分必须大于第2部分
004011F9    3BF8            cmp     edi, eax                       ; 注册码的第一部分与第三部分比较
004011FB    7E 46           jle     short 00401243                 ; 注册码的第1部分必须大于第3部分
004011FD    3BD8            cmp     ebx, eax                       ; 注册码的第二部分与第三部分比较
004011FF    7E 42           jle     short 00401243                 ; 注册码的第2部分必须大于第3部分
00401201    FF75 FC         push    dword ptr [ebp-4]              ; 取输入的注册名
00401204    E8 87FEFFFF     call    00401090                       ; 对注册名的处理(跟进)
这段代码要求注册码的3部分满足:第一部分大于第二部分大于第三部分
所以根据要求将注册码改为:6789-5678-1234
----------------------------------------------------------------------
跟进对注册名处理的CALL。
00401090    53              push    ebx                            ; 来到这里
00401091    56              push    esi
00401092    57              push    edi
00401093    8B7C24 10       mov     edi, dword ptr [esp+10]        ; 使EDI等于注册名
00401097    57              push    edi
00401098    33DB            xor     ebx, ebx                       ; EBX清零
0040109A    E8 81030000     call    00401420                       ; 取注册名的位数
0040109F    33F6            xor     esi, esi                       ; ESI清零
004010A1    59              pop     ecx                            ; ECX等于注册名
004010A2    85C0            test    eax, eax
004010A4    7E 26           jle     short 004010CC
004010A6    0FBE143E        movsx   edx, byte ptr [esi+edi]        ; 取注册名每一位的ASCII码
004010AA    8BCA            mov     ecx, edx                       ; 使ECX=EDX
004010AC    81F2 AA000000   xor     edx, 0AA                       ; 注册名每一位的ASCII码与0AA做XOR运算(结果设为B)
004010B2    C1F9 04         sar     ecx, 4                         ; 注册名每一位的ASCII码右移(结果设为C)
004010B5    0FAFD1          imul    edx, ecx                       ; 将两个处理的结果相乘(结果设为D)B*C=D
004010B8    0FAFD1          imul    edx, ecx                       ; 将D再与C相乘得到E(D*C=E)
004010BB    8BCE            mov     ecx, esi
004010BD    83E1 01         and     ecx, 1
004010C0    C1E1 02         shl     ecx, 2
004010C3    D3E2            shl     edx, cl
004010C5    03DA            add     ebx, edx                       ; 将每一步得到的E相加得到En
004010C7    46              inc     esi                            ; 每计算一次ESI+1
004010C8    3BF0            cmp     esi, eax                       ; 计算完了吗?
004010CA  ^ 7C DA           jl      short 004010A6                 ; 继续循环计算
004010CC    5F              pop     edi
004010CD    8BC3            mov     eax, ebx                       ; 使EAX等于En
通过一系列计算得到En
例如:lovetc所计算出的En等于5C1B2。
----------------------------------------------------------------------
返回到这里:
0040120B    8D45 E8         lea     eax, dword ptr [ebp-18]        ; 储存计算后的结果En
0040120E    57              push    edi
0040120F    6A 02           push    2
00401211    6A 00           push    0
00401213    50              push    eax
00401214    E8 09FEFFFF     call    00401022                       ; 关键CALL,跟进
00401219    83C4 14         add     esp, 14
0040121C    84C0            test    al, al
0040121E    74 23           je      short 00401243
00401220    57              push    edi                            ; EDI等于En
00401221    6A 02           push    2
00401223    8D45 EC         lea     eax, dword ptr [ebp-14]
00401226    6A 00           push    0
00401228    50              push    eax
00401229    E8 F4FDFFFF     call    00401022                       ; 关键CALL,跟进
0040122E    83C4 10         add     esp, 10
00401231    84C0            test    al, al
00401233    74 0E           je      short 00401243
00401235    6A 00           push    0
00401237    68 A8604000     push    004060A8                       ; success
0040123C    68 6C604000     push    0040606C                       ; congratulations, you did it.\nnow write keygen and tutorial.
00401241    EB 0C           jmp     short 0040124F
00401243    6A 00           push    0
00401245    68 64604000     push    00406064                       ; haha
0040124A    68 54604000     push    00406054                       ; get lost looser
----------------------------------------------------------------------
来到关键CALL
00401022    55              push    ebp
00401023    8BEC            mov     ebp, esp
00401025    51              push    ecx
00401026    51              push    ecx
00401027    8B55 14         mov     edx, dword ptr [ebp+14]
0040102A    56              push    esi
0040102B    8B75 08         mov     esi, dword ptr [ebp+8]
0040102E    57              push    edi
0040102F    52              push    edx
00401030    8955 F8         mov     dword ptr [ebp-8], edx
00401033    FF75 10         push    dword ptr [ebp+10]
00401036    56              push    esi
00401037    E8 C4FFFFFF     call    00401000
0040103C    83C4 0C         add     esp, 0C
0040103F    84C0            test    al, al
00401041    75 49           jnz     short 0040108C
00401043    8B45 0C         mov     eax, dword ptr [ebp+C]
00401046    3B45 10         cmp     eax, dword ptr [ebp+10]
00401049    74 3B           je      short 00401086
0040104B    8B3C86          mov     edi, dword ptr [esi+eax*4]   
0040104E    8D48 01         lea     ecx, dword ptr [eax+1]
00401051    894D 0C         mov     dword ptr [ebp+C], ecx
00401054    8BF7            mov     esi, edi                       
00401056    33C9            xor     ecx, ecx                     
00401058    8955 14         mov     dword ptr [ebp+14], edx        
0040105B    F7DE            neg     esi                           
0040105D    8B45 14         mov     eax, dword ptr [ebp+14]        
00401060    0175 14         add     dword ptr [ebp+14], esi        
00401063    50              push    eax
00401064    03CF            add     ecx, edi
00401066    FF75 10         push    dword ptr [ebp+10]
00401069    894D FC         mov     dword ptr [ebp-4], ecx
0040106C    FF75 0C         push    dword ptr [ebp+C]
0040106F    FF75 08         push    dword ptr [ebp+8]
00401072    E8 ABFFFFFF     call    00401022
00401077    83C4 10         add     esp, 10
0040107A    84C0            test    al, al
0040107C    75 0E           jnz     short 0040108C
0040107E    8B4D FC         mov     ecx, dword ptr [ebp-4]         
00401081    3B4D F8         cmp     ecx, dword ptr [ebp-8]         
00401084  ^ 7C D7           jl      short 0040105D               
00401086    32C0            xor     al, al
00401088    5F              pop     edi
00401089    5E              pop     esi
0040108A    C9              leave
0040108B    C3              retn
关键CALL的作用就是用
对En和输入的注册码第一部分进行取余计算:例:5C1B2 % 6789。
得到的结果作为注册码第2部分
再用:En和上一步计算的结果进行取余计算:结果作为注册码第三部分。

但是注册码的三部分必须满足1>2>3,且3部分都要大于1000

所以关键就是要找到一个合适的四位数作为注册码的第1部分。
例如:8000。
首先:5C1B2 % 8000=41b2
然后:5C1B2 % 41b2=1c66
所以注册名lovetc对应的
注册码就是8000-41b2-1c66
--------------------------------------------------------------------
整个过程比较简单,问题的关键就是找到一个合适4位字符作为注册码的第一部分。
找那个合适的数很是麻烦,最后为了方便起见
注册码是用后来找到的KEYGEN计算出来的(见谅)
---------------------------------------------------------------------
【版权声明】本文只为交流,转载清保留作者及文章完整性


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 47147
活跃值: (20455)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
谢谢 逍遥风 写了这么多好文章,年底推出的CrackMe专辑份量就足了。
2006-7-23 12:39
0
雪    币: 97697
活跃值: (200834)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
3
sustain.
2006-7-23 14:10
0
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
4
呵呵!多谢看雪大哥的鼓励。
继续努力学习。。。。。。
2006-7-23 16:26
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
have studying ,thx
2006-7-23 18:36
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
跟随逍遥风兄学习,支持!
2006-7-30 11:16
0
雪    币: 191
活跃值: (205)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
7
学习,
2006-7-30 12:15
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看了半天看不出这个是计算mod
2016-3-31 09:11
0
游客
登录 | 注册 方可回帖
返回
//