第二個CrackMe的破解 (6千字)

看雪資料發表於2001-08-17

CrackMe1.0的破解
                                Wrote By NYDoll

  自從研究CCG的CrackMe之後 便開始對CrackMe這個東西很感興趣,所以自己也想作出一個來,所以上網下載了一些,回來
研究想借鑑一下經驗,我們來看看這個CrackMe,比較典型BC編寫的,有它特定的結構,試試你就知道了,比較適合初學者破解,即使你寫不出序號產生器,找出註冊嗎是應該一點問題都沒有的,然後慢慢就可以看懂演算法,到時候寫序號產生器的容易了。^_^ 羅嗦了好多,我們還是回來看看程式:

    我用的斷點是BPX HMEMCPY,算得上是一個萬能斷點了,一般的程式用這個斷點都可以攔下來。
來到這裡,我們開始步步觀察演算法:

* Reference To: USER32.GetDlgItem, Ord:0000h
                                  |
:004010B6 E8E79B0000              Call 0040ACA2
:004010BB 8BF0                    mov esi, eax
:004010BD 8D8548FFFFFF            lea eax, dword ptr [ebp+FFFFFF48]
:004010C3 50                      push eax //使用者名稱入棧
:004010C4 E867050000              call 00401630
:004010C9 59                      pop ecx
:004010CA 8945D8                  mov dword ptr [ebp-28], eax //將使用者名稱壓入地址[EBP-28]
:004010CD 8D95E4FEFFFF            lea edx, dword ptr [ebp+FFFFFEE4]
:004010D3 52                      push edx //註冊碼入棧
:004010D4 E857050000              call 00401630
:004010D9 59                      pop ecx
:004010DA 68EAB04000              push 0040B0EA
:004010DF E84C050000              call 00401630
:004010E4 59                      pop ecx
:004010E5 680EB14000              push 0040B10E
:004010EA E841050000              call 00401630
:004010EF 59                      pop ecx
:004010F0 837DD803                cmp dword ptr [ebp-28], 00000003 //對比使用者名稱位數是否小於3
:004010F4 7E7B                    jle 00401171 //小於或者等於則跳轉到:00401171
:004010F6 90                      nop
:004010F7 90                      nop
:004010F8 90                      nop
:004010F9 90                      nop
:004010FA 33C9                    xor ecx, ecx //ECX暫存器清零
:004010FC 33D2                    xor edx, edx //EDX暫存器清零
:004010FE 33DB                    xor ebx, ebx //EBX暫存器清零
:00401100 33C0                    xor eax, eax //EAX暫存器清零
:00401102 837DD832                cmp dword ptr [ebp-28], 00000032 //對比使用者名稱位數是否小於50
:00401106 7D69                    jge 00401171 //大於或者等於則跳轉到:00401171
:00401108 90                      nop
:00401109 90                      nop
:0040110A 90                      nop
:0040110B 90                      nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040111C(C)
|
:0040110C 0FBE840D48FFFFFF        movsx eax, byte ptr [ebp+ecx-000000B8] //依次取使用者名稱的每一位放入EAX
:00401114 41                      inc ecx //ECX暫存器加一
:00401115 33C1                    xor eax, ecx //將EAX和ECX暫存器的值進行異或運算後放入EAX暫存器
:00401117 03D8                    add ebx, eax //EBX存放每次迴圈後EAX值的累加結果
:00401119 3B4DD8                  cmp ecx, dword ptr [ebp-28] //檢測使用者名稱的字元是否取完
:0040111C 75EE                    jne 0040110C //取完則跳出迴圈
:0040111E 6BC006                  imul eax, 00000006 //將使用者名稱最後一位字元與ECX暫存器的值異或後的結果乘以6,然後將結果儲存到EAX中。
:00401121 C1E307                  shl ebx, 07 //EBX暫存器的值邏輯左移7,結果存放到EDX暫存器中
:00401124 03C3                    add eax, ebx //將EAX暫存器和EBX暫存器中的值相加。
:00401126 8945C8                  mov dword ptr [ebp-38], eax //將結果壓入地址[EBP-38]中
:00401129 FF75C8                  push [ebp-38] //壓入結果

* Possible StringData Ref from Data Obj ->"%lX"
                                  |
:0040112C 6838B44000              push 0040B438                //---\
:00401131 8D8D80FEFFFF            lea ecx, dword ptr [ebp+FFFFFE80]  //    \
:00401137 51                      push ecx                 //    \
:00401138 E8873D0000              call 00404EC4                //      \
:0040113D 83C40C                  add esp, 0000000C             //      > 將上面的計算結果轉換成16進位制,它的十六進位制值就是真正的註冊碼。
:00401140 8D8580FEFFFF            lea eax, dword ptr [ebp+FFFFFE80]     //      /
:00401146 50                      push eax                 //    /
:00401147 8D95E4FEFFFF            lea edx, dword ptr [ebp+FFFFFEE4]  //    /
:0040114D 52                      push edx                  //---/

* Reference To: KERNEL32.lstrcmpA, Ord:0000h
                                  |
:0040114E E8339C0000              Call 0040AD86 //對比真假註冊碼
:00401153 85C0                    test eax, eax
:00401155 750D                    jne 00401164 //若對比失敗,則跳轉。

* Possible StringData Ref from Data Obj ->"恭喜您! 如果您能編寫出這個CrackMe的KeyGen, "
                                        ->"請寫一個教程給我 ;).          "  //註冊成功資訊!
                                        ->"          "
                                  |
:00401157 683CB44000              push 0040B43C
:0040115C 56                      push esi

* Reference To: USER32.SetWindowTextA, Ord:0000h
                                  |
:0040115D E8289B0000              Call 0040AC8A
:00401162 EB18                    jmp 0040117C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401155(C)
|

* Possible StringData Ref from Data Obj ->"這個註冊碼是無效的!! 請再試一遍... "
                                        ->": <尚未註冊>        "  //註冊失敗資訊!
                                  |
:00401164 6890B44000              push 0040B490
:00401169 56                      push esi

* Reference To: USER32.SetWindowTextA, Ord:0000h
                                  |
:0040116A E81B9B0000              Call 0040AC8A
:0040116F EB0B                    jmp 0040117C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004010F4(C), :00401106(C)
|

* Possible StringData Ref from Data Obj ->"使用者名稱必須為 4個字元以上 50個字元一下 "
                                        ->"!!                    " //註冊名或者註冊碼位數不符時的提示資訊
                                  |
:00401171 68C9B44000              push 0040B4C9
:00401176 56                      push esi

* Reference To: USER32.SetWindowTextA, Ord:0000h
                                  |
:00401177 E80E9B0000              Call 0040AC8A

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401162(U), :0040116F(U)
|
:0040117C 5F                      pop edi
:0040117D 5E                      pop esi
:0040117E 5B                      pop ebx
:0040117F 8BE5                    mov esp, ebp
:00401181 5D                      pop ebp
:00401182 C3                      ret

//接下來我們來總結一下演算法,舉例如使用者名稱為NYDoll,CrackMe依次取出使用者名稱的每一位字元,轉換成十進位制,然後
//與當前字元的位數進行異或運算,然後將每次異或運算後的值累加到EBX暫存器中,NYDoll的累加結果為559,然後
//將累加結果邏輯左移7位,將其結果儲存到EBX中。我的結果為71552
//將註冊名的最後一位與註冊名的位數進行異或運算,其值乘以6,然後將結果儲存到EAX暫存器中,即l與6進行異或運算
//然後再乘以6,結果為636。
//將71552與636的和72188的16進位制值119FC入棧,即119FC為NYDoll相對應的註冊碼。

相關文章