萬能五筆2001註冊碼分析及暴力破解 ---可憐的思考者 (27千字)
此軟體比較複雜,未註冊前,給出註冊框,並限定了使用次數,使用兩百次之後,不能繼續使用,哪怕是輸入正確的註冊碼也不行,重灌也不行。輸入註冊碼之後,軟體退出,在每次啟動時都要重新判斷註冊碼正確與否。
它在註冊時採用了從電腦獲取電腦碼,並將輸入的註冊碼進行計算,算得的值同電腦碼進行比較,相等則表示註冊正確。由於每臺電腦的電腦碼不同,保證了一個註冊碼只能夠用於同一臺電腦。
若用序號產生器的方法進行註冊,由於在某些使用者的機子上,已經超過了使用次數。這時註冊已經晚了。所以沒辦法,最後還是採取暴力破解更可行。
在註冊方面,作者設定了很多的障礙:輸入的註冊碼有固定的前四位和後四位,只有中間的幾位才參與計算;在程式入口,也設定了相當多的障礙,加了許多的判斷,讓我幾乎迷失在無窮的跳轉中,即使在子程式也加入了跳轉。最後很無賴,只好跟蹤正確註冊的程式,才找到正確的路徑。
寫的有點長,對不起大家。
以下是對註冊碼的分析,然後是再對其進行暴力破解
執行TRW,裝入!WNM,在出現對話方塊時,下BPX HMEMCPY,大家都是成年人,不用我說得太具體吧。
跟蹤到以下程式碼:
016F:0048CB74 MOV EDX,[00496D34] 此處存的是“tt98
0615"
016F:0048CB7A MOVSX EAX,CX
016F:0048CB7D MOV DL,[EDX+EAX] 依次取出8,9,t,t
016F:0048CB80 CMP DL,3F
016F:0048CB83
JZ 0048CB8B
016F:0048CB85 CMP
[ESP+EAX+1C],DL 依次輸入的註冊碼的第4,3,2,1位
016F:0048CB89 JNZ
0048CB8F
016F:0048CB8B DEC CX
016F:0048CB8D JNS 0048CB74
以上為比較前面四個位元組是否為 tt98
016F:0048CB8F CMP CX,BYTE
-01
016F:0048CB93 JNZ 0048CB9A
016F:0048CB95
MOV EBP,01 =1
可能表示首四位是正確的
016F:0048CB9A MOV EDI,[00496CBC]
為 "0615"
016F:0048CBA0 MOV ECX,FFFFFFFF
016F:0048CBA5 SUB EAX,EAX
016F:0048CBA7 REPNE SCASB
016F:0048CBA9 NOT
ECX
016F:0048CBAB
DEC ECX
算出為4位
016F:0048CBAC LEA EDI,[ESP+1C]
為輸入的註冊碼
016F:0048CBB0 MOV DX,CX
016F:0048CBB3
SUB EAX,EAX
016F:0048CBB5 MOV
ECX,FFFFFFFF
016F:0048CBBA REPNE SCASB
016F:0048CBBC NOT
ECX
016F:0048CBBE DEC
ECX 算出輸入的註冊碼位數
016F:0048CBBF SUB CX,DX
減去4位
016F:0048CBC2 TEST CX,CX
016F:0048CBC5 JNG 0048CBF6
016F:0048CBC7
XOR SI,SI
016F:0048CBCA TEST DX,DX
016F:0048CBCD JNG 0048CBF0
016F:0048CBCF
MOV EAX,[00496CBC] 存的是0615的地址
016F:0048CBD4
MOVSX EDI,SI
016F:0048CBD7 MOV AL,[EAX+EDI]
0615中的0
016F:0048CBDA CMP AL,3F
小於F
016F:0048CBDC JZ
0048CBE9
016F:0048CBDE MOVSX EBX,CX
016F:0048CBE1
ADD EBX,EDI
016F:0048CBE3 CMP
[ESP+EBX+1C],AL
016F:0048CBE7 JNZ 0048CBF0
016F:0048CBE9 INC SI
016F:0048CBEB CMP
DX,SI
016F:0048CBEE JG 0048CBCF
以上幾行比較後四位是否為0615
016F:0048CBF0 CMP
DX,SI
016F:0048CBF3 JNZ 0048CBF6
016F:0048CBF5
INC EBP 由48CB95,可知道
EBP=2,可能表示首四位和末四位都正確
016F:0048CBF6 CMP EBP,BYTE
+02
016F:0048CBF9 JZ 0048CC05
跳到下面,
016F:0048CBFB MOV EBP,FFFFFFFE
016F:0048CC00 JMP 0048CD05
016F:0048CC05
MOV EDI,[00496D34] 此處存的是“tt98 0615"
016F:0048CC0B MOV ECX,FFFFFFFF
016F:0048CC10 SUB EAX,EAX
016F:0048CC12
REPNE SCASB
016F:0048CC14 NOT ECX
ecx=5,這幾行好像沒什麼用
016F:0048CC16
SUB EAX,EAX
016F:0048CC18 LEA
ESI,[ESP+ECX+1B] 為輸入的註冊碼後的第五位,即tt98後面的一位的地址
016F:0048CC1C MOV
EDI,ESI
016F:0048CC1E
MOV ECX,FFFFFFFF
016F:0048CC23 REPNE SCASB
016F:0048CC25 NOT ECX
ecx=b,即tt98後面剩餘的位數+1,包括0615
016F:0048CC27 MOV
EDI,[00496CBC] edi為0615地址
016F:0048CC2D
SUB EAX,EAX
016F:0048CC2F LEA EDX,[ECX-01]
edx=a,即tt98後面剩餘的位數
016F:0048CC32
MOV ECX,FFFFFFFF
016F:0048CC37 REPNE SCASB
016F:0048CC39 NOT ECX
016F:0048CC3B DEC
ECX ECX=4
016F:0048CC3C MOV EAX,ESI
016F:0048CC3E SUB EAX,ECX
即輸入的註冊碼位置
016F:0048CC40 MOV ECX,ESI
016F:0048CC42 MOV BYTE [EAX+EDX],00
即輸入註冊碼的倒數第四位處,改位0,
以便於下面呼叫函式判斷註冊碼中部(除tt98和
0165)的位數
016F:0048CC46 CALL
00491A20 !! : 判斷輸入的字串是否滿足要求,見子程式1
016F:0048CC4B TEST EAX,EAX
016F:0048CC4D JNZ 0048CC59
eax=1時,正確,跳轉
016F:0048CC4F MOV
EBP,FFFFFFFD
016F:0048CC54 JMP 0048CD05
016F:0048CC59 MOV EDX,004930E8
此時存的“0604”字元
016F:0048CC5E MOV ECX,ESI
ESI為中間註冊碼首位地址
016F:0048CC60 MOV
EBP,FFFFFFFC
016F:0048CC65 CALL 00491A70
將其由字串轉換成二進位制的數,見子程式2
016F:0048CC6A
CMP WORD [00496D28],BYTE +01
016F:0048CC72 MOV
ESI,EAX
016F:0048CC74 JNZ 0048CCCF
016F:0048CC76 MOV DI,[00496D2E]
016F:0048CC7D
MOV EDX,[00496CB0]
016F:0048CC83 SHR
DI,08
016F:0048CC87 MOV CX,[00496D2E]
016F:0048CC8E AND CX,FF
016F:0048CC93 CALL
0048C790
016F:0048CC98 ADD ESI,EAX
016F:0048CC9A TEST DI,DI
016F:0048CC9D JNZ
0048CCA9
016F:0048CC9F MOV EDX,[00496CB4]
016F:0048CCA5 MOV ECX,EDI
016F:0048CCA7
JMP SHORT 0048CCB4
016F:0048CCA9 MOV
CX,DI
016F:0048CCAC MOV EDX,[00496CB4]
016F:0048CCB2 INC CX
016F:0048CCB4 CALL
0048C790
016F:0048CCB9 MOV ECX,EAX
016F:0048CCBB TEST ECX,ECX
016F:0048CCBD JNZ
0048CCC6
016F:0048CCBF MOV EBP,FFFFFFFB
016F:0048CCC4 JMP SHORT 0048CCFC
016F:0048CCC6
MOV EAX,ESI
016F:0048CCC8 CDQ
016F:0048CCC9 IDIV ECX
016F:0048CCCB MOV
EBP,EDX
016F:0048CCCD JMP SHORT 0048CCFC
016F:0048CCCF CMP WORD [00496D28],BYTE +02
016F:0048CCD7 JNZ 0048CCFC
016F:0048CCD9
MOV DX,[00496D2E] 存的是 63 64,即6463
016F:0048CCE0 MOV EAX,[00496CB4]
輸入的註冊人名地址
016F:0048CCE5 PUSH EAX
016F:0048CCE6
MOV ECX,[00496CB0] 也是 輸入的註冊人名地址
016F:0048CCEC
PUSH ECX
016F:0048CCED MOV ECX,[00496AC4]
取出17EF7,十進位制為98039,即我機子上的電腦碼
016F:0048CCF3 CALL
0048C820 是由註冊人名和電腦碼算出一個數值
!!! 若將此值換算成十進位制,即為正確的中間註冊碼
016F:0048CCF8 MOV EBP,EAX
016F:0048CCFA SUB EBP,ESI
016F:0048CCFC TEST EBP,EBP
016F:0048CCFE JZ 0048CD29
!!! 此值與原算得的二進位制數比較,
相等表示輸入的註冊碼正確,應跳轉
016F:0048CD00 MOV EBP,FFFFFFFB
016F:0048CD05 TEST EBP,EBP
016F:0048CD07
JNL 0048CD29
016F:0048CD09 INC WORD [ESP+12]
016F:0048CD0E MOV AX,[ESP+12]
016F:0048CD13 CMP [00496D38],AX
016F:0048CD1A
JG NEAR 0048C913
016F:0048CD20 JMP
SHORT 0048CD29
016F:0048CD22 MOV EBP,[ESP+84]
016F:0048CD29 XOR ESI,ESI
016F:0048CD2B TEST EBP,EBP
016F:0048CD2D
JL NEAR 0048CE08 若註冊碼正確,不跳
016F:0048CD33 MOV AX,[ESP+12]
016F:0048CD38 CMP [00496D38],AX
016F:0048CD3F
JNG NEAR 0048CE08
016F:0048CD45 MOV
EDX,01
016F:0048CD4A MOV ECX,[ESP+12]
016F:0048CD4E CALL 0048C4C0
此處是判斷是否過時,若過時,即使註冊碼對,也不能用
016F:0048CD53 TEST
EAX,EAX
016F:0048CD55 JZ 0048CDCD
過時則不跳轉,應跳轉
016F:0048CD57 PUSH
DWORD 1010
016F:0048CD5C MOV EBX,[00496D3C]
016F:0048CD62 MOVSX EAX,WORD [ESP+16]
016F:0048CD67
SHL EAX,02
016F:0048CD6A PUSH DWORD
004930E0
016F:0048CD6F LEA ECX,[EAX+EAX*2]
016F:0048CD72 LEA EDX,[ECX+ECX*4]
016F:0048CD75
MOV ECX,[ESP+1C]
016F:0048CD79 MOV
EAX,[EDX+EBX+34]
016F:0048CD7D PUSH EAX
016F:0048CD7E
PUSH ECX
016F:0048CD7F CALL `USER32!MessageBoxA`
出現過時框
016F:0048CD85 MOV ECX,[ESP+14]
016F:0048CD89 PUSH DWORD 1001
016F:0048CD8E
PUSH ECX
016F:0048CD8F CALL `USER32!GetDlgItem`
016F:0048CD95 MOV ECX,EAX
016F:0048CD97
CALL 0048B910
016F:0048CD9C MOV [00496A5E],SI
016F:0048CDA3 PUSH ESI
016F:0048CDA4 MOV
[004931C0],SI
016F:0048CDAB PUSH DWORD 8002
016F:0048CDB0 PUSH DWORD 0111
016F:0048CDB5
MOV ECX,[00496C80]
016F:0048CDBB PUSH
ECX
016F:0048CDBC CALL `USER32!SendMessageA`
016F:0048CDC2
POP EBP
016F:0048CDC3 POP EDI
016F:0048CDC4 POP ESI
016F:0048CDC5
POP EBX
016F:0048CDC6 ADD ESP,A8
016F:0048CDCC RET
016F:0048CDCD MOV
EAX,[ESP+14]
016F:0048CDD1 MOV ECX,[00496C80]
016F:0048CDD7 MOV BYTE [00496AB3],02
016F:0048CDDE
PUSH EAX
016F:0048CDDF PUSH DWORD 8000
016F:0048CDE4 PUSH DWORD 0111
016F:0048CDE9 PUSH
ECX
016F:0048CDEA CALL `USER32!SendMessageA`
016F:0048CDF0 MOV ECX,[ESP+14]
016F:0048CDF4
PUSH BYTE +01
016F:0048CDF6 PUSH ECX
016F:0048CDF7 CALL `USER32!EndDialog`
016F:0048CDFD
POP EBP
016F:0048CDFE POP EDI
016F:0048CDFF POP ESI
016F:0048CE00
POP EBX
016F:0048CE01 ADD ESP,A8
016F:0048CE07 RET
子程式1
016F:00491A20 PUSH ESI
016F:00491A21 MOV
EDX,ECX edx,ecx為註冊碼中間部分的起始地址
016F:00491A23
PUSH EDI
016F:00491A24 XOR ESI,ESI
016F:00491A26 MOV EDI,EDX
edi為註冊碼中間部分的起始地址
016F:00491A28 MOV
ECX,FFFFFFFF
016F:00491A2D SUB EAX,EAX
016F:00491A2F REPNE SCASB
016F:00491A31 NOT
ECX
016F:00491A33 DEC
ECX 中間部分的位數
016F:00491A34
TEST ECX,ECX
016F:00491A36 JNG
00491A56 位數小於1,跳轉,但不出錯;位數大於1,不跳
以下迴圈判斷中間註冊碼是否滿足條件
016F:00491A38 MOV
AL,[EDX+ESI] 取出字元
016F:00491A3B CMP
AL,30
016F:00491A3D JC 00491A5E
016F:00491A3F
CMP AL,39
016F:00491A41 JA
00491A5E 是否在0~9之間,不再,則出錯輸出EAX=0
016F:00491A43 INC
ESI
016F:00491A44 MOV
EDI,EDX
016F:00491A46 MOV ECX,FFFFFFFF
016F:00491A4B
SUB EAX,EAX
016F:00491A4D REPNE SCASB
016F:00491A4F
NOT ECX
016F:00491A51 DEC ECX
016F:00491A52 CMP ECX,ESI
016F:00491A54
JG 00491A38 迴圈判斷
016F:00491A56
MOV EAX,01 正確,輸出EAX=1
016F:00491A5B
POP EDI
016F:00491A5C POP ESI
016F:00491A5D RET
016F:00491A5E XOR
EAX,EAX
016F:00491A60 POP EDI
016F:00491A61
POP ESI
016F:00491A62 RET
子程式2
016F:00491A70 SUB
ESP,BYTE +08
016F:00491A73 MOV
[ESP+04],EDX 0604字串
016F:00491A77 PUSH
EBX
016F:00491A78 MOV DWORD [ESP+04],00
016F:00491A80 PUSH ESI
016F:00491A81 PUSH
EDI
016F:00491A82 PUSH EBP
016F:00491A83
MOV ESI,01
016F:00491A88 PUSH ECX
016F:00491A89 MOV EBP,ECX
ESI為中間註冊碼首位地址
016F:00491A8B CALL
`KERNEL32!lstrlenA` 求出中間註冊碼長度
016F:00491A91 LEA
EDI,[EAX-01] EDI=長度-1
016F:00491A94
TEST EDI,EDI
016F:00491A96 JL 00491AD3
長度大於0則不跳,否則出錯
以下迴圈
016F:00491A98 MOV
BL,[EBP+EDI+00] 依次取出中間註冊碼末位,末位-1,......
016F:00491A9C
CMP BL,30
016F:00491A9F JC
00491AAA
016F:00491AA1 CMP BL,39
016F:00491AA4
JA 00491AAA
是否在0~9之間
016F:00491AA6 TEST EDI,EDI
016F:00491AA8 JNL 00491AB8
肯定要跳
016F:00491AAA MOV ECX,00493504
016F:00491AAF MOV EDX,[ESP+14]
016F:00491AB3
CALL 00491600
016F:00491AB8 XOR
EAX,EAX
016F:00491ABA LEA ECX,[ESI+ESI*4]
由491A83知,esi開始1,算得ECX=5,以後依次esi*10,即10,100,1000.....
016F:00491ABD
MOV AL,BL
016F:00491ABF SUB
EAX,BYTE +30 將此字元轉換成二進位制數
016F:00491AC2 IMUL
EAX,ESI
016F:00491AC5
LEA ESI,[ECX*2+`DOSMGR_BackFill_Allowed`]
DOSMGR_BackFill_Allowed=0
算得ESI=10
016F:00491ACC ADD [ESP+10],EAX
原來的字元
016F:00491AD0 DEC EDI
016F:00491AD1
JNS 00491A98 迴圈,直至所有的字元
016F:00491AD3 MOV EAX,[ESP+10]
由上面的分析,可知此子程式將輸入中間註冊碼
016F:00491AD7 POP
EBP
由字串轉換成二進位制的數
016F:00491AD8
POP EDI
016F:00491AD9 POP ESI
016F:00491ADA POP EBX
016F:00491ADB
ADD ESP,BYTE +08
016F:00491ADE RET
總結一下,以上程式碼將輸入的註冊碼進行判斷,首先看註冊碼的起始和結尾的固定碼是否正確,若正確判斷中間註冊碼是否滿足一定要求。然後取出本機的電腦碼,由其算出正確的註冊碼。
關鍵點:
在48ccf3處,算出正確的註冊碼(要轉換成十進位制才能看到)
在48ccfe處與輸入的註冊碼進行比較。
上面的這一段,其實是我的失敗經驗。因為我不知怎麼亂搞,把註冊次數搞成了0次,這下即使得到註冊碼也沒用了,只好用暴力法破解。
分析檔案入口處的程式碼:
016F:0048E01D MOV ECX,01
016F:0048E022
CALL 00490AA0
取得電腦資訊碼98039
016F:0048E027 XOR
EAX,EAX
016F:0048E029 MOV AX,[00496D32]
016F:0048E02F TEST
AH,C0
ah=f0
016F:0048E032 JNZ NEAR
0048E066 應該跳轉
016F:0048E038 XOR EAX,EAX
016F:0048E03A
MOV AX,[00496D32]
016F:0048E040 TEST
AH,10
016F:0048E043 JZ NEAR 0048E066
[496d32]=10 表示次數已用完
016F:0048E049
PUSH BYTE +00
016F:0048E04B PUSH DWORD 8003
016F:0048E050 PUSH DWORD 0111
016F:0048E055
MOV EAX,[00496C80]
016F:0048E05A PUSH
EAX
016F:0048E05B CALL `USER32!SendMessageA`
次數已用完錯誤框
016F:0048E061 JMP
0048E06B
016F:0048E066 CALL 0048E680
016F:0048E06B
CMP DWORD [00493170],BYTE +00
016F:0048E072 JZ
NEAR 0048E08E
016F:0048E078 MOV ECX,[EBP-50]
016F:0048E07B CALL 00490CC0
若登錄檔中的註冊碼不對,顯示開始的註冊框,裡面又有跳轉見子程式3,要改
016F:0048E080 MOV [EBP-50],EAX
016F:0048E083
MOV ECX,[EBP-50]
016F:0048E086 CALL
00490D80
若註冊碼正確,即顯示正確框,裡面有跳轉,見子程式4,要改
016F:0048E08B MOV
[EBP-50],EAX
016F:0048E08E CMP DWORD [EBP-50],BYTE
+01
016F:0048E092 JNZ NEAR 0048E0BF
016F:0048E098
XOR EAX,EAX
016F:0048E09A MOV
AX,[004931B8]
016F:0048E0A0 TEST EAX,EAX
016F:0048E0A2
JZ NEAR 0048E0BF
016F:0048E0A8 XOR
EAX,EAX
016F:0048E0AA MOV AX,[00496A9F]
016F:0048E0B0 TEST EAX,EAX
016F:0048E0B2 JZ
NEAR 0048E0BF
016F:0048E0B8 DEC WORD
[00496A9F]
016F:0048E0BF CMP DWORD [EBP-50],BYTE
+01
016F:0048E0C3 JNZ NEAR 0048E1D5
016F:0048E0C9
XOR EAX,EAX
016F:0048E0CB MOV
AX,[004931B8]
016F:0048E0D1 TEST EAX,EAX
016F:0048E0D3
JZ NEAR 0048E1D5
016F:0048E0D9 XOR
EAX,EAX
016F:0048E0DB MOV AX,[0049317C]
016F:0048E0E1 TEST AL,02
016F:0048E0E3 JNZ
NEAR 0048E107
016F:0048E0E9 CMP DWORD
[00493178],BYTE +00
016F:0048E0F0 JZ NEAR 0048E107
應該跳轉
016F:0048E0F6
XOR EAX,EAX
016F:0048E0F8 MOV
AX,[0049317C]
016F:0048E0FE OR EAX,BYTE +02
016F:0048E101 MOV [0049317C],AX
016F:0048E107
XOR EAX,EAX
016F:0048E109 MOV
AX,[0049317C]
016F:0048E10F TEST AL,02
016F:0048E111
JZ NEAR 0048E146
應該跳轉
016F:0048E117 CALL 00491250
016F:0048E11C MOV [004931B8],AX
016F:0048E122
XOR EAX,EAX
016F:0048E124 MOV
AX,[004931B8]
016F:0048E12A TEST EAX,EAX
016F:0048E12C
JNZ NEAR 0048E146
016F:0048E132 PUSH
BYTE +00
016F:0048E134 PUSH DWORD 004930B8
016F:0048E139
PUSH DWORD 004932DC
016F:0048E13E PUSH BYTE
+00
016F:0048E140 CALL `USER32!MessageBoxA`
server is full 錯誤資訊
016F:0048E146
XOR EAX,EAX
016F:0048E148 MOV
AX,[0049317C]
016F:0048E14E TEST AL,01
016F:0048E150
JNZ NEAR 0048E1D5
016F:0048E156 CMP
DWORD [00493174],BYTE +00
016F:0048E15D JZ
NEAR 0048E198 應該跳轉
016F:0048E163 MOVSX EAX,WORD [00496AB1]
016F:0048E16A
TEST EAX,EAX
016F:0048E16C JL NEAR
0048E198
016F:0048E172 MOVSX EAX,WORD [00496AB1]
016F:0048E179 SHL EAX,02
016F:0048E17C LEA
EAX,[EAX+EAX*2]
016F:0048E17F LEA
EAX,[EAX+EAX*4]
016F:0048E182 MOV ECX,[00496D3C]
016F:0048E188 XOR EDX,EDX
016F:0048E18A
MOV DX,[EAX+ECX+28]
016F:0048E18F TEST
DL,08
016F:0048E192 JNZ NEAR 0048E1C4
016F:0048E198
CMP DWORD [00493174],BYTE +00
016F:0048E19F JZ
NEAR 0048E1D5
應該跳轉
016F:0048E1A5 MOVSX EAX,WORD [00496AB1]
016F:0048E1AC TEST EAX,EAX
016F:0048E1AE JNL
NEAR 0048E1D5
016F:0048E1B4 XOR EAX,EAX
016F:0048E1B6 MOV AX,[00496D44]
016F:0048E1BC
TEST AL,08
016F:0048E1BE JZ NEAR 0048E1D5
016F:0048E1C4 XOR EAX,EAX
016F:0048E1C6
MOV AX,[0049317C]
016F:0048E1CC OR
EAX,BYTE +01
016F:0048E1CF MOV [0049317C],AX
016F:0048E1D5 XOR EAX,EAX
016F:0048E1D7
MOV AX,[0049317C]
016F:0048E1DD TEST
EAX,EAX
016F:0048E1DF JZ NEAR 0048E2B7
應該跳轉
016F:0048E1E5
CMP DWORD [EBP-50],BYTE +01
016F:0048E1E9 JNZ
NEAR 0048E2B7
016F:0048E1EF XOR EAX,EAX
016F:0048E1F1 MOV AX,[004931B8]
016F:0048E1F7
TEST EAX,EAX
016F:0048E1F9 JZ NEAR
0048E2B7
016F:0048E1FF LEA EAX,[EBP-64]
016F:0048E202
PUSH EAX
016F:0048E203 MOV EDX,00496C70
016F:0048E208 LEA ECX,[00496AA1]
016F:0048E20E
CALL 00491B50
016F:0048E213 MOV ECX,00496A40
016F:0048E218 ADD ECX,BYTE +61
016F:0048E21B
MOV EDX,[EAX]
016F:0048E21D MOV
[ECX],EDX
016F:0048E21F MOV EDX,[EAX+04]
016F:0048E222
MOV [ECX+04],EDX
016F:0048E225 MOV
EDX,[EAX+08]
016F:0048E228 MOV [ECX+08],EDX
016F:0048E22B MOV EAX,[EAX+0C]
016F:0048E22E
MOV [ECX+0C],EAX
016F:0048E231 CALL
00490640
016F:0048E236 TEST EAX,EAX
016F:0048E238
JNZ NEAR 0048E24D
016F:0048E23E MOV
EDX,004932D4
016F:0048E243 MOV ECX,004932B8
016F:0048E248 CALL 00491600
016F:0048E24D MOV
EDX,00496B40
016F:0048E252 LEA ECX,[00496AA1]
016F:0048E258 CALL 00490BC0
016F:0048E25D MOV
ECX,[EBP+10]
016F:0048E260 CALL 00491100
016F:0048E265 TEST EAX,EAX
016F:0048E267 JZ
NEAR 0048E295
016F:0048E26D CALL 00491080
016F:0048E272 MOV [EBP-50],EAX
016F:0048E275
PUSH BYTE +00
016F:0048E277 PUSH BYTE +00
016F:0048E279 PUSH BYTE +10
016F:0048E27B MOV
EAX,[00496C80]
016F:0048E280 PUSH EAX
016F:0048E281 CALL `USER32!SendMessageA`
016F:0048E287
MOV WORD [004931B8],00
016F:0048E290 JMP
0048E2B7
016F:0048E295 MOV DWORD
[EBP-50],00
016F:0048E29C MOV WORD [004931B8],00
016F:0048E2A5 PUSH BYTE +00
016F:0048E2A7 PUSH
BYTE +00
016F:0048E2A9 PUSH BYTE +10
016F:0048E2AB
MOV EAX,[00496C80]
016F:0048E2B0 PUSH
EAX
016F:0048E2B1 CALL `USER32!SendMessageA`
016F:0048E2B7
LEA EDX,[EBP-4C]
016F:0048E2BA LEA
ECX,[EBP-54]
016F:0048E2BD CALL 0048E3D0
016F:0048E2C2
MOV [EBP-48],EAX
016F:0048E2C5 PUSH
BYTE +00
016F:0048E2C7 PUSH BYTE +00
016F:0048E2C9
PUSH BYTE +10
016F:0048E2CB MOV EAX,[00496C80]
016F:0048E2D0 PUSH EAX
016F:0048E2D1 CALL
`USER32!SendMessageA`
016F:0048E2D7 CMP
DWORD [00493180],BYTE +02
016F:0048E2DE JZ NEAR
0048E32C
要改
016F:0048E2E4 CMP DWORD [EBP-50],BYTE
+01
016F:0048E2E8 JNZ NEAR 0048E32C
要改
016F:0048E2EE
XOR EAX,EAX
016F:0048E2F0 MOV
AX,[004931B8]
016F:0048E2F6 TEST EAX,EAX
016F:0048E2F8
JZ NEAR 0048E32C
要改
016F:0048E2FE MOV
EAX,[EBP+08]
016F:0048E301 PUSH EAX
016F:0048E302
PUSH DWORD 004931A8
016F:0048E307 CALL `USER32!UnregisterClassA`
016F:0048E30D XOR EAX,EAX
016F:0048E30F
MOV AX,[004931BC]
016F:0048E315 TEST
EAX,EAX
016F:0048E317 JZ NEAR 0048E32C
要改
016F:0048E31D MOV EAX,[EBP-4C]
016F:0048E320
PUSH EAX
016F:0048E321 LEA EDX,[EBP-54]
016F:0048E324 MOV ECX,[EBP-48]
016F:0048E327
CALL 0048E360
好了,就是它,但此過程中又有跳轉,見下面子程式5,要改
016F:0048E32C CMP
DWORD [EBP-54],BYTE +00
016F:0048E330 JZ
NEAR 0048E33E
016F:0048E336 MOV ECX,[EBP-54]
016F:0048E339 CALL 004915F0
016F:0048E33E MOV
EAX,[EBP-50]
016F:0048E341 PUSH EAX
016F:0048E342 CALL `KERNEL32!ExitProcess`
016F:0048E348
MOV EAX,[EBP-50]
016F:0048E34B JMP
0048E350
016F:0048E350 POP EDI
016F:0048E351
POP ESI
016F:0048E352 POP EBX
016F:0048E353 LEAVE
016F:0048E354 RET
10
子程式3:若上次退出前輸入的註冊碼正確,此處不顯示註冊碼對話方塊,否則要顯示
016F:00490CC0 TEST BYTE [00496D33],80
016F:00490CC7
PUSH ESI
016F:00490CC8 PUSH EDI
016F:00490CC9
MOV ESI,ECX
016F:00490CCB JZ
NEAR 00490D7A
016F:00490CD1 CMP WORD [004931B8],BYTE
+00
016F:00490CD9 JNZ 00490CE4
016F:00490CDB
CMP BYTE [00496AB3],02
016F:00490CE2 JNZ
00490D15
跳轉
016F:00490CE4 CMP
WORD [00496AB1],BYTE +00
016F:00490CEC JL
00490D0B
016F:00490CEE MOVSX EAX,WORD [00496AB1]
016F:00490CF5 SHL EAX,02
016F:00490CF8 LEA
ECX,[EAX+EAX*2]
016F:00490CFB MOV
EAX,[00496D3C]
016F:00490D00 LEA EDX,[ECX+ECX*4]
016F:00490D03 CMP WORD [EDX+EAX+02],BYTE +00
016F:00490D09 JNZ 00490D15
016F:00490D0B
CMP WORD [00493160],BYTE +02
016F:00490D13 JNZ
00490D7A
016F:00490D15 XOR EDX,EDX
016F:00490D17 MOV ECX,68
016F:00490D1C
MOV ESI,00
016F:00490D21 CALL 00491510
016F:00490D26 MOV EDX,00496B20
016F:00490D2B
MOV ECX,EAX
016F:00490D2D MOV
[00496CC0],EAX
016F:00490D32 CALL 0048D4E0
016F:00490D37
TEST EAX,EAX
016F:00490D39 JZ 00490D4C
應該跳轉
016F:00490D3B MOV EDX,0048D010
016F:00490D40
MOV ECX,00496B20
016F:00490D45 CALL
0048D680
即註冊對話方塊
016F:00490D4A MOV ESI,EAX
016F:00490D4C MOV ECX,00496B20
到此處
016F:00490D51 CALL
0048B200
016F:00490D56 MOV EAX,[00496CC0]
016F:00490D5B MOV EDI,[00497394]
016F:00490D61
PUSH EAX
016F:00490D62 CALL EDI
016F:00490D64
PUSH EAX
016F:00490D65 CALL `KERNEL32!GlobalUnlock`
016F:00490D6B MOV EAX,[00496CC0]
016F:00490D70
PUSH EAX
016F:00490D71 CALL EDI
016F:00490D73
PUSH EAX
016F:00490D74 CALL `KERNEL32!GlobalFree`
016F:00490D7A MOV EAX,ESI
016F:00490D7C
POP EDI
016F:00490D7D POP ESI
子程式4:若上次退出前輸入的註冊碼正確,顯示註冊人和註冊名框,否則不顯示
016F:00490D80
TEST BYTE [00496D33],40
016F:00490D87 PUSH
ESI
016F:00490D88 PUSH EDI
016F:00490D89 MOV
ESI,ECX
016F:00490D8B JZ NEAR 00490E86
016F:00490D91 CMP WORD [00496AB1],BYTE +00
016F:00490D99 JL 00490DBC
016F:00490D9B MOVSX
EAX,WORD [00496AB1]
016F:00490DA2 SHL EAX,02
016F:00490DA5 LEA ECX,[EAX+EAX*2]
016F:00490DA8
MOV EAX,[00496D3C]
016F:00490DAD LEA
EDX,[ECX+ECX*4]
016F:00490DB0 CMP WORD [EDX+EAX+02],BYTE
+00
016F:00490DB6 JNZ NEAR 00490E86
016F:00490DBC
CMP WORD [004931B8],BYTE +00
016F:00490DC4 JZ
00490DCF
016F:00490DC6 CMP BYTE [00496AB3],02
016F:00490DCD JZ 00490E00
016F:00490DCF
TEST BYTE [00496D33],80
016F:00490DD6 JNZ
NEAR 00490E86 不跳
016F:00490DDC TEST BYTE [00496D33],10
016F:00490DE3
JZ 00490E00
應該跳轉
016F:00490DE5 MOV ECX,01
016F:00490DEA CALL 0048E700
次數用完對話方塊
016F:00490DEF TEST EAX,EAX
016F:00490DF1 JZ 00490E00
016F:00490DF3
TEST BYTE [00496D33],10
016F:00490DFA JNZ
NEAR 00490E86
016F:00490E00 XOR EDX,EDX
016F:00490E02 MOV ECX,6D
016F:00490E07
MOV ESI,00
016F:00490E0C CALL 00491510
016F:00490E11 MOV EDX,00496C90
016F:00490E16
MOV ECX,EAX
016F:00490E18 MOV
[00496D1C],EAX
016F:00490E1D CALL 0048D4E0
016F:00490E22
TEST EAX,EAX
016F:00490E24 JZ 00490E37
016F:00490E26 MOV EDX,0048D6C0
016F:00490E2B
MOV ECX,00496C90
016F:00490E30 CALL
0048D680 註冊正確框,正確的註冊名和註冊碼
016F:00490E35 MOV ESI,EAX
016F:00490E37
MOV ECX,00496C90
016F:00490E3C CALL
0048B200
016F:00490E41 MOV EAX,[00496D1C]
016F:00490E46 MOV EDI,[00497394]
016F:00490E4C
PUSH EAX
016F:00490E4D CALL EDI
016F:00490E4F
PUSH EAX
016F:00490E50 CALL `KERNEL32!GlobalUnlock`
016F:00490E56 MOV EAX,[00496D1C]
016F:00490E5B
PUSH EAX
016F:00490E5C CALL EDI
016F:00490E5E
PUSH EAX
016F:00490E5F CALL `KERNEL32!GlobalFree`
016F:00490E65 TEST BYTE [00496D33],10
016F:00490E6C
JNZ 00490E86
016F:00490E6E PUSH BYTE
+00
016F:00490E70 MOV EAX,[00496C80]
016F:00490E75
PUSH DWORD 8000
016F:00490E7A PUSH DWORD
0111
016F:00490E7F PUSH EAX
016F:00490E80 CALL
`USER32!SendMessageA`
016F:00490E86 MOV
EAX,ESI
016F:00490E88 POP EDI
016F:00490E89
POP ESI
ret
子程式5:進入正確的萬能五筆程式,但進入前要判斷一下。
016F:0048E360 PUSH ESI
016F:0048E361
PUSH EDI
016F:0048E362 MOV ESI,EDX
016F:0048E364 MOV EDI,[ESP+0C]
016F:0048E368
MOV EDX,[ECX+02]
016F:0048E36B XOR
EDX,[ECX+06]
016F:0048E36E XOR EDX,[ECX+0A]
016F:0048E371 ADD EDI,EDX
016F:0048E373
XOR EDX,EDX
016F:0048E375 MOV
EAX,[ECX+06]
016F:0048E378 INC EDX
016F:0048E379
XOR [EDI+EDX*4-04],EAX
016F:0048E37D INC
EDX
016F:0048E37E MOV EAX,[ECX+0A]
016F:0048E381 XOR [EDI+EDX*4-04],EAX
016F:0048E385
CMP EDX,BYTE +14
016F:0048E388 JL
0048E375
016F:0048E38A MOV ECX,[ESI]
016F:0048E38C CALL 004915F0
016F:0048E391 MOV
DWORD [ESI],00
016F:0048E397 CMP
WORD [004931B8],BYTE +00
016F:0048E39F JZ 0048E3AD
要改
016F:0048E3A1 CMP WORD [004931C0],BYTE +00
016F:0048E3A9
JZ 0048E3AD
016F:0048E3AB CALL EDI
就是它,正確的程式在此處,TNND,找死我了
016F:0048E3AD PUSH BYTE +00
016F:0048E3AF PUSH DWORD 00493328
016F:0048E3B4
PUSH DWORD 00493318
016F:0048E3B9 PUSH BYTE
+00
016F:0048E3BB CALL `USER32!MessageBoxA`
016F:0048E3C1
POP EDI
016F:0048E3C2 POP ESI
016F:0048E3C3 RET 04
好,總結以下,其實就是不斷的判斷障礙,
註冊對話方塊在 48e07b call的子程式中。
正確的程式程式碼藏在 48e3ab call的子程式中。
知道了這一點(也是最困難的一點),就容易對症下藥了。
其中要更改的地方有:
490d39
48e086 改為nop
48e2de
48e2e8
48e2f8
48e39f
48e3a9
當然不一定非得如此,只要能跳到48e3ab,其他的跳轉應該也行。
相關文章
- 萬能五筆的破解 (6千字)2001-07-09
- 巧妙變換;及可憐的小老鼠分析2013-08-07
- 可憐的小老鼠;及Google賽馬分析2013-08-06Go
- 轉帖:智慧五筆5.04註冊方法 (1千字)2001-06-24
- 萬能五筆2002分析筆記!2015-11-15筆記
- 五筆輸入通1.x註冊演算法分析
(10千字)2015-11-15演算法
- Netty原始碼分析--Channel註冊(上)(五)2019-07-02Netty原始碼
- BabyGame 破解方法及註冊碼錶 (1千字)2001-07-04GAM
- CPUCOOL 5.1000註冊碼分析 (6千字)2001-01-19
- 流光2001完全暴力破解 (3千字)2001-08-14
- 萬能五筆2000a+破解《作者:BanhouseMaster》 (3千字)2000-09-12AST
- Cleaner 3.2註冊分析 (18千字)2001-12-09
- Konvertor 3.03的註冊碼演算法模組的分析
(7千字)2015-11-15演算法
- Universe 1.63註冊碼生成分析及序號產生器原碼(上) (2千字)2001-11-12
- 檔案密使2.6註冊碼分析詳解 (11千字)2001-11-30
- Green Tea 2.60註冊碼演算法分析 (3千字)2000-07-17演算法
- Flash ActionScript Tool 的註冊碼! (22千字)2001-05-04
- 《TxEdit 4.6》的註冊碼破解 (11千字)2001-07-28
- 優軟精靈畫筆之大天使3.0註冊演算法分析及KeyGen (3千字)2001-11-10演算法
- SuperCleaner 2.31註冊碼演算法分析 - OCG (13千字)2002-04-02演算法
- Registry Crawler 4.0註冊碼演算法分析 - OCG
(20千字)2002-04-07演算法
- 空檔接龍助手2.01註冊碼分析。 (6千字)2003-01-13
- UltraEdit-32
10註冊碼演算法分析 (19千字)2003-05-17演算法
- getPassword2.3註冊碼計算分析過程 (3千字)2001-11-07
- **********.exe註冊碼演算法分析--高手莫笑 (31千字)2015-11-15演算法
- S-DEMO2 註冊分析 (14千字)2002-06-25
- DreamWaver3.0註冊流程分析 (17千字)2001-09-10
- 註冊碼演算法 (2千字)2001-01-14演算法
- 幻影2003 V3.0註冊碼分析
(12千字)2003-01-25
- Magic convertor 2.8註冊碼演算法分析
- OCG (9千字)2015-11-15演算法
- 《飛天餐飲娛樂管理系統》註冊碼演算法分析以及暴力破解2000-12-10演算法
- 一種非明碼比較程式的註冊------NS-SHAFT註冊碼破解 (9千字)2015-11-15
- File Shredder 2000破解筆記及註冊演算法 (5千字)2003-04-30筆記演算法
- Theme Builder註冊碼分析2015-11-15UI
- ShadowDefender 註冊碼 分析2024-08-17
- GetRight 4.5b 註冊分析 (33千字)2001-12-09
- FolderView 1.7
註冊演算法分析 (14千字)2015-11-15View演算法
- DataFit V7.0.36註冊過程的分析 (9千字)2001-11-09