檔案密使2.6註冊碼分析詳解 (11千字)

看雪資料發表於2001-11-30

破解者:tieji
破解時間:2001-11-28
破解工具:TRW2000 V1.23  W32dasm黃金版
作者主頁:http://www.wjmshome.com

啟動軟體,彈出註冊框,填入註冊資訊:
註冊名:caoxinyu 
註冊碼:5432112345  <----隨便填
開啟TRW2000,下斷點bpx hmemcpy,點確定,被攔下。
按F10來到:

:00413887 E816540000              Call 00418CA2
:0041388C 8D8E001B0000            lea ecx, dword ptr [esi+00001B00]
:00413892 E817C2FFFF              call 0040FAAE  <=====關鍵的call,分析比較註冊碼,跟進
:00413897 85C0                    test eax, eax  <=====eax是否為零
:00413899 751E                    jne 004138B9  <=====不為零,正確就跳[多經典!]
:0041389B 6A40                    push 00000040

* Possible StringData Ref from Data Obj ->"warning"
                                  |
:0041389D 68C4614200              push 004261C4

* Possible StringData Ref from Data Obj ->"註冊碼錯誤,請重新輸入"
                                  |
:004138A2 6820784200              push 00427820
:004138A7 8BCB                    mov ecx, ebx

=============================================================================================
關鍵的cal:
* Referenced by a CALL at Addresses:
|:0040702B  , :00413892 
|
:0040FAAE B820B64100              mov eax, 0041B620

* Reference To: MSVCRT._EH_prolog, Ord:0042h
                                  |         
:0040FAB3 E858960000              Call 00419110
:0040FAB8 83EC2C                  sub esp, 0000002C  <==== esp-0x2c
:0040FABB 56                      push esi          <==== 儲存esi
:0040FABC 57                      push edi          <==== 儲存edi
:0040FABD 8B7D08                  mov edi, dword ptr [ebp+08]  <==== 將ebp+08的內容傳給edi,即將
                                                                使用者名稱caoxinyu所在的地址傳給edi
:0040FAC0 33F6                    xor esi, esi      <====esi清零
:0040FAC2 8975EC                  mov dword ptr [ebp-14], esi  <====ebp-14處的內容清零
:0040FAC5 8B4FF8                  mov ecx, dword ptr [edi-08]  <====將使用者名稱長度(本例為8)傳給ecx
:0040FAC8 3BCE                    cmp ecx, esi      <====比較使用者名稱長度是否為零
:0040FACA 0F84AD000000            je 0040FB7D        <====為零跳到0040FB7D (本例不為零不跳)
:0040FAD0 83F920                  cmp ecx, 00000020  <====比較使用者名稱長度是否為32位
:0040FAD3 7E03                    jle 0040FAD8      <====小於32位就跳到0040FAD8
:0040FAD5 6A20                    push 00000020      <====大於32位就將32給ecx
:0040FAD7 59                      pop ecx            <====既使用者名稱長度擷取前32位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAD3(C)
|
:0040FAD8 3BCE                    cmp ecx, esi      <====使用者名稱長度與零比較
:0040FADA 7E13                    jle 0040FAEF      <====小於等於零就跳
:0040FADC 8D45C8                  lea eax, dword ptr [ebp-38]    <====eax裝入ebp-38的地址
:0040FADF 2BF8                    sub edi, eax      <====edi-eax-->edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAED(C)
|
:0040FAE1 8D4435C8                lea eax, dword ptr [ebp+esi-38]  <====eax裝入ebp+esi-38的地址
:0040FAE5 46                      inc esi            <====esi加1
:0040FAE6 3BF1                    cmp esi, ecx      <====esi與ecx使用者名稱長度比較
:0040FAE8 8A1407                  mov dl, byte ptr [edi+eax]    <====將使用者名稱的一個字母傳給dl
:0040FAEB 8810                    mov byte ptr [eax], dl        <====將使用者名稱的一個字母放入eax所
                                                                    在的地址中
:0040FAED 7CF2                    jl 0040FAE1        <====迴圈將使用者名稱caoxinyu依次放到eax所指的地址中

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FADA(C)                        <====使用者名稱長度小於等於零跳到這裡
|
:0040FAEF 83F920                  cmp ecx, 00000020  <==== 比較使用者名稱長度是否為32位
:0040FAF2 53                      push ebx            <==== 儲存ebx
:0040FAF3 7D2C                    jge 0040FB21        <==== 大於等於32位跳
:0040FAF5 8D7DC8                  lea edi, dword ptr [ebp-38]  <====edi裝入ebp-38所指的內容
:0040FAF8 8D45C8                  lea eax, dword ptr [ebp-38]  <====eax裝入ebp-38所指的內容
                                                          即將放有caoxinyu處的地址-->edi,eax
:0040FAFB 4F                      dec edi            <====edi-1
:0040FAFC 2BC7                    sub eax, edi        <====eax-edi--->eax 即eax=0x1
:0040FAFE 8945F0                  mov dword ptr [ebp-10], eax  <====eax-->[ebp-10]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB1F(C)
|
:0040FB01 8A1C0F                  mov bl, byte ptr [edi+ecx]  <====將使用者名稱的最後一個字母(本例為u)-->bl
:0040FB04 8D340F                  lea esi, dword ptr [edi+ecx]<====esi裝入u所在的地址
:0040FB07 0FB6C3                  movzx eax, bl    <====將u放入eax
:0040FB0A 99                      cdq              <====雙位元組擴充套件 edx為00000000
:0040FB0B F7F9                    idiv ecx        <====除ecx 即0x75/0x8 即eax中為0xE,edx中為0x5
:0040FB0D 8BD0                    mov edx, eax    <====eax-->edx 即edx為0xE
:0040FB0F 8AC3                    mov al, bl      <====bl--->al  即al=0x75
:0040FB11 F6E9                    imul cl          <====乘cl 即0x75*0x8=0x3A8 --->eax
:0040FB13 02D0                    add dl, al      <====dl+al-->dl 即0xE+0xA8=0xB6-->dl
:0040FB15 8B45F0                  mov eax, dword ptr [ebp-10]  <====[ebp-10]--->eax=0x1
:0040FB18 41                      inc ecx          <====ecx+1
:0040FB19 83F920                  cmp ecx, 00000020    <====ecx與32比較,即使用者名稱長度是否到了32位
:0040FB1C 881430                  mov byte ptr [eax+esi], dl  <====將0xB6放到使用者名稱的最後一個字母
                                                                  "u"的後面
:0040FB1F 7CE0                    jl 0040FB01        <====使用者名稱長度是不到32位就迴圈

注:上面這個迴圈是將使用者名稱不到32位的補齊到32位,以使用者名稱為caoxinyu為例計算如下:
第一次迴圈:
      0x75/0x8=0xE
      0x75*0x8=0xA8 因用al暫存器計算,故0x3A8-->0xA8
      0xE+0xA8=0xB6
    將計算所得的0xB6接到使用者名稱caoxinyu的後面,變為:63616F78696E7975B6
第二次迴圈:
      0xB6/0x9=0x14
      0xB6*0x9=0x66
      0x14+0x66=0x7A
    將計算所得的0x7A再接到使用者名稱的後面,變為:63616F78696E7975B67A
如此經過32-8次迴圈,補齊到32位的使用者名稱為:
    63616F78696E7975B67AD0021839220000000000000000000000000000000000
     
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAF3(C)                        <===========使用者名稱長度大於等於32位跳到這裡
|
:0040FB21 33F6                    xor esi, esi                  <====esi清零
:0040FB23 8975F0                  mov dword ptr [ebp-10], esi  <====ebp-10處內容清零

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB59(C)                 
|                                <======四次迴圈開始,為何是四次迴圈,見下面說明:
:0040FB26 8B45F0                  mov eax, dword ptr [ebp-10]    <====將ebp-10的內容-->eax
:0040FB29 806435E800              and byte ptr [ebp+esi-18], 00  <====和0x00與
:0040FB2E 8D4C35E8                lea ecx, dword ptr [ebp+esi-18]<====ebp+esi-18的地址-->ecx
:0040FB32 6A04                    push 00000004          <====
:0040FB34 99                      cdq                    <====雙位元組擴充套件
:0040FB35 5B                      pop ebx                <====將0x4放入ebx
:0040FB36 33FF                    xor edi, edi          <====edi清零
:0040FB38 F7FB                    idiv ebx              <====eax/0x4
:0040FB3A 8A19                    mov bl, byte ptr [ecx] <====bl=0
:0040FB3C 8D4405C8                lea eax, dword ptr [ebp+eax-38] <====將ebp+eax-38的地址-->eax
                            即ebp-38為使用者名稱所在的地方,ebp+eax-38 就是使用者名稱所在的地址+eax 
                             
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB49(C)
|
:0040FB40 8A1438                  mov dl, byte ptr [eax+edi]  <====將eax+edi所在的內容-->dl
:0040FB43 32DA                    xor bl, dl                  <====bl^dl-->bl
:0040FB45 47                      inc edi                    <====edi+1
:0040FB46 83FF08                  cmp edi, 00000008          <====迴圈8次
:0040FB49 7CF5                    jl 0040FB40                 
:0040FB4B 8345F020                add dword ptr [ebp-10], 00000020  <====加20
:0040FB4F 46                      inc esi                          <====esi+1
:0040FB50 817DF080000000          cmp dword ptr [ebp-10], 00000080  <====與0x80比較
:0040FB57 8819                    mov byte ptr [ecx], bl            <====bl-->[ecx]
:0040FB59 7CCB                    jl 0040FB26          <====迴圈,因每次加20,加到80,所以迴圈四次

注:上面有兩個迴圈,迴圈中套迴圈
  因已得到32位的使用者名稱16進製為:63616F78696E7975B67AD0021839220000000000000000000000000000000000
第一次迴圈:(第一個字母c , 16進製為:63)
  0x63^0x61=0x2
    0x2^0x6F=0x6D
  如此迴圈8次最後得到0x1E
第二次迴圈:(第九個字母16進製為:B6)
    0xB6^0x7A=0xCC
    0xCC^0xD0=0x1C
  如此迴圈8次最後得到0x1D
第三次迴圈:同理最後得到00
第四次迴圈:同理最後得到00
將四次迴圈所得的結果反過來看00001D1E即為正確的註冊碼,不過要將他轉換為十進位制數.               

:0040FB5B 8B45EC                  mov eax, dword ptr [ebp-14]    <====[ebp-14]-->eax
:0040FB5E 6A03                    push 00000003                  <====
:0040FB60 59                      pop ecx                        <====3放入ecx
:0040FB61 5B                      pop ebx                        <====還原ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB71(C)
|
:0040FB62 0FB6540DE8              movzx edx, byte ptr [ebp+ecx-18]
:0040FB67 03C2                    add eax, edx          <=====eax+edx-->eax
:0040FB69 85C9                    test ecx, ecx
:0040FB6B 7406                    je 0040FB73          <====ecx為零跳
:0040FB6D C1E008                  shl eax, 08          <====左移8位
:0040FB70 49                      dec ecx              <====ecx-1
:0040FB71 79EF                    jns 0040FB62
                                            <=====上面的迴圈將正確的註冊碼放入eax中

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB6B(C)
|
:0040FB73 2B450C                  sub eax, dword ptr [ebp+0C] <====將eax中正確的註冊碼與輸入的假
                                                                  註冊碼相減
:0040FB76 F7D8                    neg eax            <====取eax二補碼
:0040FB78 1BC0                    sbb eax, eax        <====借位減
:0040FB7A 40                      inc eax            <====eax+1 若為0表示註冊碼錯誤,0x1表示正確
:0040FB7B 8BF0                    mov esi, eax        <====eax-->esi 註冊標記儲存

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FACA(C)                                  <====使用者名稱長度為零跳到這裡
|
:0040FB7D 834DFCFF                or dword ptr [ebp-04], FFFFFFFF
:0040FB81 8D4D08                  lea ecx, dword ptr [ebp+08]

* Reference To: MFC42.Ordinal:0320, Ord:0320h
                                  |
:0040FB84 E8E78F0000              Call 00418B70
:0040FB89 8B4DF4                  mov ecx, dword ptr [ebp-0C]
:0040FB8C 8BC6                    mov eax, esi        <====esi--->eax 註冊標記傳給eax
:0040FB8E 5F                      pop edi
:0040FB8F 5E                      pop esi
:0040FB90 64890D00000000          mov dword ptr fs:[00000000], ecx
:0040FB97 C9                      leave
:0040FB98 C20800                  ret 0008

寫得真累,希望能給初學者有幫助,也望各位大俠指教........

相關文章