《chm幫助編輯器V2.61》註冊碼破解心得: (11千字)

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

軟體名稱:chm幫助編輯器V2.61
下載地址:http://kshii.51.net/
破解工具:TRW1.23註冊版
破解目的:註冊碼及其產生機制
破解過程:在註冊介面裡,用bpx hmemcpy等方法都攔不住,說明作者在這方面下了很大功夫,但百密難免一疏,在使用31次後會跳出一個NAG,提示試用期已到,這是cracker最喜歡見到的:),此時按^N,並下命令PMODULE,又回到NAG畫面,點確定後立刻被攔,往上找就會看到如下程式碼:
016F:0047A204  LEA      EAX,[EBP+FFFFFEF7]
016F:0047A20A  PUSH    EAX
016F:0047A20B  PUSH    DWORD 0047A4F8        |
016F:0047A210  PUSH    DWORD 0047A4FC        |讀取win.ini的[AgeSet]中的
016F:0047A215  PUSH    DWORD 0047A504        |Pnum的值,即軟體序號
016F:0047A21A  CALL    `KERNEL32!GetProfileStringA` |
016F:0047A21F  CMP      BYTE [EBP+FFFFFEF7],00
016F:0047A226  JNZ      NEAR 0047A2C7         如Pnum非空則跳過去
016F:0047A22C  CALL    00402A4C           |
016F:0047A231  LEA      EAX,[EBP-04]         |
016F:0047A234  CALL    00403BF4           |
016F:0047A239  MOV      EBX,0A            |
016F:0047A23E  MOV      EAX,49            |
016F:0047A243  CALL    00402BF4           |
016F:0047A248  MOV      ESI,EAX            |
016F:0047A24A  INC      ESI              |
016F:0047A24B  LEA      EAX,[EBP+FFFFFEF0]      |隨機產生新的軟體序號
016F:0047A251  PUSH    EAX              |(10個字元)
016F:0047A252  MOV      ECX,01            |
016F:0047A257  MOV      EDX,ESI            |
016F:0047A259  MOV      EAX,0047A514         |
016F:0047A25E  CALL    0040407C           |
016F:0047A263  MOV      EDX,[EBP+FFFFFEF0]      |
016F:0047A269  LEA      EAX,[EBP-04]         |
016F:0047A26C  CALL    00403E7C           |
016F:0047A271  DEC      EBX              |
016F:0047A272  JNZ      0047A23E           |
016F:0047A274  MOV      EAX,[0048B8E0]
016F:0047A279  MOV      EAX,[EAX+06C0]
016F:0047A27F  MOV      EDX,[EBP-04]
016F:0047A282  CALL    004306F0
016F:0047A287  MOV      EDX,0047A568
016F:0047A28C  MOV      EAX,[0048B8E0]
016F:0047A291  CALL    004306F0
016F:0047A296  MOV      EAX,[EBP-04]
016F:0047A299  CALL    00404038
016F:0047A29E  PUSH    EAX
016F:0047A29F  PUSH    DWORD 0047A4FC
016F:0047A2A4  PUSH    DWORD 0047A504
016F:0047A2A9  CALL    `KERNEL32!WriteProfileStringA` 將軟體序號寫入win.ini
016F:0047A2AE  PUSH    DWORD 0047A5C0
016F:0047A2B3  PUSH    DWORD 0047A5C8
016F:0047A2B8  PUSH    DWORD 0047A504
016F:0047A2BD  CALL    `KERNEL32!WriteProfileStringA` 寫入Pwes,即試用次數
016F:0047A2C2  JMP      0047A4BD
016F:0047A2C7  LEA      EAX,[EBP+FFFFFEEC]
016F:0047A2CD  LEA      EDX,[EBP+FFFFFEF7]
016F:0047A2D3  MOV      ECX,0101
016F:0047A2D8  CALL    00403E24
016F:0047A2DD  MOV      EDX,[EBP+FFFFFEEC]
016F:0047A2E3  MOV      EAX,[0048B8E0]
016F:0047A2E8  MOV      EAX,[EAX+06C0]
016F:0047A2EE  CALL    004306F0
016F:0047A2F3  PUSH    DWORD 0100
016F:0047A2F8  LEA      EAX,[EBP+FFFFFEF7]
016F:0047A2FE  PUSH    EAX
016F:0047A2FF  PUSH    DWORD 0047A4F8
016F:0047A304  PUSH    DWORD 0047A5D0
016F:0047A309  PUSH    DWORD 0047A504
016F:0047A30E  CALL    `KERNEL32!GetProfileStringA` 讀取Pset值
016F:0047A313  LEA      EAX,[EBP+FFFFFEE8]
016F:0047A319  LEA      EDX,[EBP+FFFFFEF7]
016F:0047A31F  MOV      ECX,0101
016F:0047A324  CALL    00403E24
016F:0047A329  MOV      EDX,[EBP+FFFFFEE8]
016F:0047A32F  MOV      EAX,[0048B8E0]
016F:0047A334  MOV      EAX,[EAX+06C8]
016F:0047A33A  CALL    004306F0
016F:0047A33F  XOR      EDX,EDX
016F:0047A341  MOV      EAX,[0048B8E0]
016F:0047A346  CALL    0047A108        這個CALL是關鍵,從這裡追進去
016F:0047A34B  MOV      EAX,[0048B8E0]
016F:0047A350  MOV      EAX,[EAX+06CC]
016F:0047A356  CMP      DWORD [EAX+0C],01F4
016F:0047A35D  JZ      NEAR 0047A4BD
 .
 .
 .
---------------------------------
016F:0047A108  PUSH    EBX
016F:0047A109  MOV      EBX,EAX
016F:0047A10B  MOV      EAX,[EBX+06BC]
016F:0047A111  MOV      EAX,[EAX+70]
016F:0047A114  CALL    00479E54    這個CALL是關鍵的關鍵,判斷註冊碼的真假,再追...
016F:0047A119  TEST    AL,AL
016F:0047A11B  JZ      0047A157
016F:0047A11D  MOV      EAX,[EBX+06BC]
016F:0047A123  MOV      EAX,[EAX+70]
016F:0047A126  CALL    00404038
016F:0047A12B  PUSH    EAX
016F:0047A12C  PUSH    DWORD 0047A15C
016F:0047A131  PUSH    DWORD 0047A164
016F:0047A136  CALL    `KERNEL32!WriteProfileStringA`
016F:0047A13B  MOV      EAX,[EBX+06CC]
016F:0047A141  MOV      DWORD [EAX+0C],01F4
016F:0047A148  MOV      EDX,0047A174
016F:0047A14D  MOV      EAX,[0048B8E0]
016F:0047A152  CALL    004306F0
016F:0047A157  POP      EBX
016F:0047A158  RET   
-----------------------------
016F:00479E54  PUSH    EBP
016F:00479E55  MOV      EBP,ESP
016F:00479E57  MOV      ECX,07
016F:00479E5C  PUSH    BYTE +00
016F:00479E5E  PUSH    BYTE +00
016F:00479E60  DEC      ECX
016F:00479E61  JNZ      00479E5C
016F:00479E63  PUSH    EBX
016F:00479E64  PUSH    ESI
016F:00479E65  MOV      [EBP-04],EAX
016F:00479E68  MOV      EAX,[EBP-04]
016F:00479E6B  CALL    00404028
016F:00479E70  XOR      EAX,EAX
016F:00479E72  PUSH    EBP
016F:00479E73  PUSH    DWORD 0047A066
016F:00479E78  PUSH    DWORD [FS:EAX]
016F:00479E7B  MOV      [FS:EAX],ESP
016F:00479E7E  MOV      BYTE [EBP-05],00 將註冊的標誌置為假
016F:00479E82  MOV      EAX,[EBP-04]
016F:00479E85  CALL    00403E74     計算註冊碼的長度
016F:00479E8A  CMP      EAX,BYTE +0D   等13嗎?
016F:00479E8D  JNZ      NEAR 0047A043   不是,說明是假的,那就在此下中斷,把win.ini
016F:00479E93  LEA      EAX,[EBP-1C]   裡的Pset值改為123456789abcd,再來吧
016F:00479E96  PUSH    EAX
016F:00479E97  MOV      ECX,02
016F:00479E9C  MOV      EDX,01
016F:00479EA1  MOV      EAX,[EBP-04]
016F:00479EA4  CALL    0040407C     取註冊碼的前2位
016F:00479EA9  MOV      EAX,[EBP-1C]
016F:00479EAC  MOV      EDX,0047A080
016F:00479EB1  CALL    00403F84
016F:00479EB6  JNZ      NEAR 0047A043  是“El”嗎?不是則假
016F:00479EBC  LEA      EAX,[EBP-20]
016F:00479EBF  PUSH    EAX
016F:00479EC0  MOV      ECX,01
016F:00479EC5  MOV      EDX,03
016F:00479ECA  MOV      EAX,[EBP-04]
016F:00479ECD  CALL    0040407C    取註冊碼的第3位
016F:00479ED2  MOV      EAX,[EBP-20]
016F:00479ED5  MOV      EDX,0047A08C
016F:00479EDA  CALL    00403F84
016F:00479EDF  JNZ      NEAR 0047A043  是“@”嗎?不是則假
016F:00479EE5  LEA      EAX,[EBP-24]
016F:00479EE8  PUSH    EAX
016F:00479EE9  MOV      ECX,01
016F:00479EEE  MOV      EDX,0A
016F:00479EF3  MOV      EAX,[EBP-04]
016F:00479EF6  CALL    0040407C    取註冊碼的第10位
016F:00479EFB  MOV      EAX,[EBP-24]
016F:00479EFE  MOV      EDX,0047A098
016F:00479F03  CALL    00403F84
016F:00479F08  JNZ      NEAR 0047A043  是“%”嗎?不是則假
016F:00479F0E  LEA      EAX,[EBP-28]
016F:00479F11  PUSH    EAX
016F:00479F12  MOV      ECX,01
016F:00479F17  MOV      EDX,0B
016F:00479F1C  MOV      EAX,[EBP-04]
016F:00479F1F  CALL    0040407C    取註冊碼的第11位
016F:00479F24  MOV      EAX,[EBP-28]
016F:00479F27  MOV      EDX,0047A0A4
016F:00479F2C  CALL    00403F84
016F:00479F31  JNZ      NEAR 0047A043  是“s”嗎?不是則假
016F:00479F37  LEA      EAX,[EBP-2C]
016F:00479F3A  PUSH    EAX
016F:00479F3B  MOV      ECX,01
016F:00479F40  MOV      EDX,0D
016F:00479F45  MOV      EAX,[EBP-04]
016F:00479F48  CALL    0040407C    取註冊碼的第13位
016F:00479F4D  MOV      EAX,[EBP-2C]
016F:00479F50  MOV      EDX,0047A0B0
016F:00479F55  CALL    00403F84
016F:00479F5A  JNZ      NEAR 0047A043 是“e”嗎?不是則假
016F:00479F60  LEA      EAX,[EBP-0C]
016F:00479F63  PUSH    EAX
016F:00479F64  MOV      ECX,06
016F:00479F69  MOV      EDX,04
016F:00479F6E  MOV      EAX,[EBP-04]
016F:00479F71  CALL    0040407C   取軟體序號的第4至9位
016F:00479F76  LEA      EAX,[EBP-30] 以下將序號的第4至9位做簡單的變換:
016F:00479F79  PUSH    EAX      如將“456789”變成“896745”
016F:00479F7A  MOV      ECX,02
016F:00479F7F  MOV      EDX,05
016F:00479F84  MOV      EAX,[EBP-0C]
016F:00479F87  CALL    0040407C
016F:00479F8C  PUSH    DWORD [EBP-30]
016F:00479F8F  LEA      EAX,[EBP-34]
016F:00479F92  PUSH    EAX
016F:00479F93  MOV      ECX,02
016F:00479F98  MOV      EDX,03
016F:00479F9D  MOV      EAX,[EBP-0C]
016F:00479FA0  CALL    0040407C
016F:00479FA5  PUSH    DWORD [EBP-34]
016F:00479FA8  LEA      EAX,[EBP-38]
016F:00479FAB  PUSH    EAX
016F:00479FAC  MOV      ECX,02
016F:00479FB1  MOV      EDX,01
016F:00479FB6  MOV      EAX,[EBP-0C]
016F:00479FB9  CALL    0040407C
016F:00479FBE  PUSH    DWORD [EBP-38]
016F:00479FC1  LEA      EAX,[EBP-0C]
016F:00479FC4  MOV      EDX,03
016F:00479FC9  CALL    00403F34
016F:00479FCE  LEA      EDX,[EBP-10]
016F:00479FD1  MOV      EAX,[0048B8E0]
016F:00479FD6  MOV      EAX,[EAX+06C0]
016F:00479FDC  CALL    004306C0     --變換到此結束--
016F:00479FE1  MOV      EBX,01
016F:00479FE6  LEA      EAX,[EBP-14]  從這裡到016F:0047A03D是一個迴圈,EBX是迴圈變數
016F:00479FE9  PUSH    EAX
016F:00479FEA  MOV      ECX,01
016F:00479FEF  MOV      EDX,EBX
016F:00479FF1  MOV      EAX,[EBP-10]
016F:00479FF4  CALL    0040407C    取軟體序號的第EBX位
016F:00479FF9  LEA      EAX,[EBP-18]
016F:00479FFC  PUSH    EAX
016F:00479FFD  MOV      EDX,07
016F:0047A002  SUB      EDX,EBX
016F:0047A004  MOV      ECX,01
016F:0047A009  MOV      EAX,[EBP-0C]
016F:0047A00C  CALL    0040407C    取註冊碼的第7-EBX
016F:0047A011  MOV      EDX,0047A0BC  在0047A0BC處有一張表:“123456789!@#$%^-*()PLWAQokmIJNuhbYGVtfcRDXeszESZrdxFTCygvUHBijnOKMplqwa”
016F:0047A016  MOV      EAX,[EBP-14]
016F:0047A019  CALL    00404160    算出註冊碼的第7-EBX位在上表中的位置
016F:0047A01E  MOV      ESI,EAX     存入ESI
016F:0047A020  MOV      EDX,0047A0BC
016F:0047A025  MOV      EAX,[EBP-18]
016F:0047A028  CALL    00404160    算出軟體序號的第EBX位在上表中的位置
016F:0047A02D  MOV      EDX,EAX     存入EDX及EAX
016F:0047A02F  DEC      EDX
016F:0047A030  CMP      ESI,EDX    ESI=EDX-1?
016F:0047A032  JZ      0047A039   是則真
016F:0047A034  INC      EAX
016F:0047A035  CMP      ESI,EAX    ESI=EAX+1?
016F:0047A037  JNZ      0047A043    不是則假
016F:0047A039  INC      EBX
016F:0047A03A  CMP      EBX,BYTE +07   共迴圈6次
016F:0047A03D  JNZ      00479FE6     --迴圈結束--
016F:0047A03F  MOV      BYTE [EBP-05],01 真註冊碼的標誌
016F:0047A043  XOR      EAX,EAX
016F:0047A045  POP      EDX
016F:0047A046  POP      ECX
016F:0047A047  POP      ECX
016F:0047A048  MOV      [FS:EAX],EDX
016F:0047A04B  PUSH    DWORD 0047A06D
016F:0047A050  LEA      EAX,[EBP-38]
016F:0047A053  MOV      EDX,0C
016F:0047A058  CALL    00403C18
016F:0047A05D  LEA      EAX,[EBP-04]
016F:0047A060  CALL    00403BF4
016F:0047A065  RET   
---------------------------------
  總結一下注冊碼的產生機制:註冊碼為13位,其中第12位為任意字元,註冊碼的形式為:El@??????%s?e,第4-9位是根據軟體序號的前6位產生的,而且不是唯一的(一個軟體序號大概對應2^6=64個註冊碼)。分析上述演算法不難做出序號產生器,不過作者的處境好象很困難,所以最好不要將序號產生器傳播。
  這裡給出幾個成功的註冊碼:
  軟體序號   註冊碼
 1234567890 El@325476%s?e
 61WM!dgQ^N El@27pAx@%s?e
  另外,從2.21版的分析中發現一個數字:“740926”,估計是作者的生日,到時別忘了給他寄份賀卡喔。

相關文章