優軟精靈畫筆之大天使3.0註冊演算法分析及KeyGen (3千字)

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

精靈畫筆之大天使3.0註冊演算法分析


作者:Maomao[CCG]
軟體:Nupaint3.exe
      金山畫王的下一代版本,效果非常不錯,適合教學使用。
下載:http://www.eusoftware.com/download/wizc30.zip
工具:Trw2000 v1.23
日期:2001-11-10

    用TRW載入Nupaint3.exe,下斷點bpx getwindowtexta後按F5返回程式。選擇程式選單“幫助->註冊”,在對話方塊中輸入註冊碼:ABCD-1234-5678-abcd,使用者名稱Maomao[CCG],按“確定”後程式中斷,下pmodule,bd *後,回到Nupaint3領空,來到了這裡:
0167:00441E1A  CALL    ESI
0167:00441E1C  LEA      ECX,[ESP+10] <=====游標在這裡
0167:00441E20  PUSH    BYTE +05
0167:00441E22  PUSH    ECX
按住F10,經過四次讀對話方塊資訊後,來到這裡:
0167:00441F1F  REP MOVSB
0167:00441F21  CALL    `SERIAL!Uncode_a_SerialNo`  <=====計算註冊碼
0167:00441F26  ADD      ESP,BYTE +04
0167:00441F29  TEST    EAX,EAX
0167:00441F2B  POP      EBP
0167:00441F2C  JNL      00441F7F            <=====不跳說明註冊失敗
0167:00441F2E  MOV      EDX,[00490C90]
0167:00441F34  MOV      ESI,[0047D480]
在算註冊碼的一行上設斷,按F5回到程式。再按“確定”,被中斷在這一行上。用F8跟進去,按住F10,一會兒來到這裡:
0167:1000132F  CMP      BYTE [ESP+04],57  <=====這裡D ESP+4可看到輸入的註冊碼
                                            取第一個字元與0x57('W')比較
0167:10001334  JNZ      1000135D
0167:10001336  CMP      BYTE [ESP+05],49  <===== 取第二個字元與0x49('I')比較
0167:1000133B  JNZ      1000135D
0167:1000133D  CMP      BYTE [ESP+06],5A  <===== 取第二個字元與0x5A('Z')比較
0167:10001342  JNZ      1000135D
0167:10001344  CMP      BYTE [ESP+07],42  <===== 取第二個字元與0x42('B')比較
0167:10001349  JNZ      1000135D         
0167:1000134B  LEA      EDX,[ESP+04]
0167:1000134F  PUSH    EDX
0167:10001350  CALL    10001270        <=====計算其它段註冊碼的call
0167:10001355  ADD      ESP,BYTE +04
0167:10001358  POP      EDI
0167:10001359  ADD      ESP,BYTE +14
0167:1000135C  RET   
    可以看出,如果輸入的註冊碼前四位不是WIZB,程式將不進行下一次判斷。在0167:10001350的call上設斷,F5回到程式。將註冊碼改為"WIZB-1234-5678-abcd",按“確定”後,TRW中斷在計算其它註冊碼的call上。用F8跟進去,來到這裡:
0167:10001270  MOV      ECX,[ESP+04] <=====匯入被重新排列的註冊碼
0167:10001274  PUSH    ESI
0167:10001275  PUSH    EDI
0167:10001276  XOR      EAX,EAX
0167:10001278  MOV      ESI,0C
0167:1000127D  LEA      EDX,[ECX+0F]  <=====取排列後的註冊碼最後一位
0167:10001280  MOVSX    EDI,BYTE [ESI+10005033] <=====取密碼錶中最後一位
                                                這裡D ESI+10005033-F可以看到用於對照的密碼錶:
                                            WIZBIK01ADE1G1AL
0167:10001287  MOVSX    ECX,BYTE [EDX]  <=====取輸入後被重列的註冊碼最後一位
                                              這裡D EDX-F可以看到被重新列後的輸入註冊碼
                                              我的被變成了:WIZBab123456cd78
0167:1000128A  SUB      ECX,EDI      <=====相減
0167:1000128C  JS      1000129C      <=====小於密碼錶字元則跳到結束
0167:1000128E  CMP      ECX,BYTE +08
0167:10001291  JNL      1000129C      <=====大於等於密碼錶字元+8也跳到結束
0167:10001293  ADD      EAX,ECX
0167:10001295  DEC      EDX
0167:10001296  DEC      ESI
0167:10001297  JNZ      10001280      <=====取下一位
0167:10001299  POP      EDI
0167:1000129A  POP      ESI
0167:1000129B  RET
  我輸入的註冊碼是"WIZB-1234-5678-abcd",被重新排列成了"WIZBab123456cd78",哈哈,只要對照一下,把它的密碼錶順序重新排列一下,就可以得到最小的註冊碼了:"WIZB-01AD-E1AL-IKG1",註冊中沒有用到使用者名稱,看來與使用者名稱無關,還是比較友好的。好了,收工~~~

做了一個KeyGen,已上傳到白菜樂園,另外也上傳到了BCG的FTP中。

相關文章