AlgoLab PtVector的破解及序號產生器的編寫 (17千字)
軟體簡介:algolab_photo_vector_v1.01 能將點陣圖轉換成向量圖!使用方便、功能強大!
下載地址:ftp://202.108.252.18/stcsr/rj/txtx/b-apv101.zip
破解工具:SoftICE 4.05,W32Dasm
說明:該軟體沒有殼,而且可以反覆註冊,真是合Cracker的脾氣。分析一下程式後,進行暴破還是很容易的,但我更喜歡看他的註冊碼的計算。
破解開始:
執行程式後,選擇Help下的About,就會進行註冊。分別填入User Name,Company Name,E-mail Address和Registration,Ctrl+D進入SoftICE,下bpx
GetWindowTextA,按註冊按鈕,程式會被攔下來,下面為用W32Dasm反編譯的註冊時的Call
* Reference To: MFC42.Ordinal:0217, Ord:0217h
|
:004171AF E8E2120200 Call
00438496 ====> GetWindowTextA
......
:004171F5 8D55E0
lea edx, dword ptr [ebp-20]
:004171F8 52
push edx
====> Registration
:004171F9 8D45E8
lea eax, dword ptr [ebp-18]
:004171FC 50
push eax
====> E-mail Address
:004171FD 8D4DDC
lea ecx, dword ptr [ebp-24]
:00417200 51
push ecx
====> User Name
:00417201 E888CFFFFF call
0041418E ====> 關鍵比對,我們將追進去
:00417206 83C40C
add esp, 0000000C
:00417209 898578FFFFFF mov dword
ptr [ebp+FFFFFF78], eax ====> eax作為判斷標誌
:0041720F 83BD78FFFFFF00 cmp dword ptr [ebp+FFFFFF78],
00000000 ====> 是否註冊成功
:00417216 7559
jne 00417271
====> 沒有則轉
......
:00417234 6A00
push 00000000
:00417236 6A00
push 00000000
* Possible StringData Ref from Data Obj ->"Successful Registration!"
|
:00417238 68740A4400 push
00440A74
* Reference To: MFC42.Ordinal:04B0, Ord:04B0h
|
:0041723D E838130200 Call
0043857A ====> MessageBoxA
:00417242 C645FC01
mov [ebp-04], 01
:00417246 8D4DF0
lea ecx, dword ptr [ebp-10]
上面的其他判斷過程略過,其中,eax=1則使用者名稱輸入錯誤;eax=2則E-mail地址輸入錯誤;eax=3則註冊碼輸入錯誤
從上面我們看出,00417201語句的call 0041418E是註冊計算和比對的關鍵,我們追進去,如下:
:004141B8 8B4D10
mov ecx, dword ptr [ebp+10]
:004141BB E860DEFEFF call
00402020
:004141C0 50
push eax
====> 註冊碼地址入棧
:004141C1 E8DF63FFFF call
0040A5A5 ====> 計算註冊碼是否正確的call
此call首先比較註冊碼長度是否等於19(13h),如果相等則將前18個註冊碼的ascii值相加,除以36(24h),餘數如果小於10,則檢測值等於相應的數字,否則檢測值等於'A'+餘數-10,即為A-Z的一個字元,如果檢測值與第19個字元相等,則註冊碼正確,返回EAX=1,否則EAX=0
4141C1語句可以這樣理解,程式建立一個子程式或函式,用來檢測註冊碼是否正確:call TestCorrect(Registration)
:004141C6 83C404
add esp, 00000004
:004141C9 8845F8
mov byte ptr [ebp-08], al
:004141CC 8B45F8
mov eax, dword ptr [ebp-08]
:004141CF 25FF000000 and eax,
000000FF
:004141D4 85C0
test eax, eax
====> 註冊碼是否正確
:004141D6 7507
jne 004141DF
====> 正確則轉
:004141D8 B803000000 mov eax,
00000003 ====> 錯誤號
:004141DD EB7F
jmp 0041425E
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004141D6(C)
|
:004141DF 8B4D10
mov ecx, dword ptr [ebp+10]
:004141E2 E839DEFEFF call
00402020 ====> 返回ecx的內容地址指標
====> 這裡指向輸入的註冊碼地址
:004141E7 50
push eax
* Reference To: MSVCRT.strlen, Ord:02BEh
|
:004141E8 E88F480200 Call
00438A7C
:004141ED 83C404
add esp, 00000004
:004141F0 8945DC
mov dword ptr [ebp-24], eax
:004141F3 8B4DDC
mov ecx, dword ptr [ebp-24]
:004141F6 51
push ecx
====> 註冊碼的長度
:004141F7 8B4D10
mov ecx, dword ptr [ebp+10]
:004141FA E821DEFEFF call
00402020
:004141FF 50
push eax
====> 註冊碼地址
:00414200 6A11
push 00000011
====> 進行計算並變換程式碼的長度
:00414202 8D55E0
lea edx, dword ptr [ebp-20]
:00414205 52
push edx
====> 進行計算並變換程式碼的存放地址
:00414206 E84362FFFF call
0040A44E ====> 程式碼變換,共17(11h)個,很重要
:0041420B 83C410
add esp, 00000010
:0041420E 8B4D08
mov ecx, dword ptr [ebp+08] ====> ecx使用者名稱地址
:00414211 E80ADEFEFF call
00402020
:00414216 50
push eax
:00414217 E8FF5CFFFF call
00409F1B ====> 進行計算
對使用者名稱變換後得到一個檢測值,結果返回到EAX
變換過程:將使用者名稱各個字元的ascii值相加,然後除以1Ah(26),餘數+"A"-0Ah即餘數+37h
:0041421C 83C404
add esp, 00000004
:0041421F 8845FC
mov byte ptr [ebp-04], al
:00414222 0FBE45E4
movsx eax, byte ptr [ebp-1C] ====> 變換程式碼的第5個值
:00414226 0FBE4DFC
movsx ecx, byte ptr [ebp-04] ====> 取出使用者名稱的計算值
:0041422A 3BC1
cmp eax, ecx
====> 進行比較
:0041422C 7407
je 00414235
====> 相等則繼續
:0041422E B801000000 mov eax,
00000001 ====> 錯誤號
:00414233 EB29
jmp 0041425E
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041422C(C)
|
:00414235 8B4D0C
mov ecx, dword ptr [ebp+0C]
:00414238 E8E3DDFEFF call
00402020
:0041423D 50
push eax
====> E-mail地址
:0041423E E8D85CFFFF call
00409F1B ====> 進行計算,過程同使用者名稱計算一樣
:00414243 83C404
add esp, 00000004
:00414246 8845F4
mov byte ptr [ebp-0C], al
:00414249 0FBE55E6
movsx edx, byte ptr [ebp-1A] ====> 變換程式碼的第7個值
:0041424D 0FBE45F4
movsx eax, byte ptr [ebp-0C] ====> 取出E-mail的計算值
:00414251 3BD0
cmp edx, eax
====> 進行比較
:00414253 7407
je 0041425C
====> 相等則轉
:00414255 B802000000 mov eax,
00000002 ====> 錯誤號
:0041425A EB02
jmp 0041425E
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414253(C)
|
:0041425C 33C0
xor eax, eax
====> 正確的eax值
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004141DD(U), :00414233(U), :0041425A(U)
|
:0041425E 8BE5
mov esp, ebp
:00414260 5D
pop ebp
:00414261 C3
ret
上面這段的關鍵是對註冊碼進行變換和對使用者名稱和E-mail地址的計算,其中,對使用者名稱和E-mail地址的計算已經說完,現在看看如何對註冊碼進行變換,即414206的call
0040A44E語句,如下:
* Referenced by a CALL at Addresses:
|:00409D73 , :0040A673 , :0040A6F6 , :00414206 , :004142DD
|
:0040A44E 55
push ebp
:0040A44F 8BEC
mov ebp, esp
:0040A451 83EC24
sub esp, 00000024
:0040A454 C745F810000000 mov [ebp-08], 00000010
====> 設初值
:0040A45B 8B4510
mov eax, dword ptr [ebp+10]
:0040A45E 8A4811
mov cl, byte ptr [eax+11] ====> 取出註冊碼的第18個字元
:0040A461 884DF4
mov byte ptr [ebp-0C], cl
:0040A464 8A55F4
mov dl, byte ptr [ebp-0C]
:0040A467 52
push edx
====> 第18個字元入棧
:0040A468 E801FDFFFF call
0040A16E ====> 進行計算,計算結果返回到eax中
上句可以看作是對某個引數進行變換的函式,如ChangeCode(edx),計算過程:如果edx(要計算的字元的ascii值)在30h-39h,則返回結果為0-9,否則返回結果為edx+"A"-0ah=edx-37h
:0040A46D 83C404
add esp, 00000004
:0040A470 8945FC
mov dword ptr [ebp-04], eax ====> 計算結果放到[ebp-04]中,為說明方便,設值為X18
:0040A473 8B4508
mov eax, dword ptr [ebp+08] ====> 變換碼的地址
:0040A476 8B4D10
mov ecx, dword ptr [ebp+10]
:0040A479 8A11
mov dl, byte ptr [ecx] ====> 取註冊碼的第1個字元
:0040A47B 8810
mov byte ptr [eax], dl ====> 放到變換碼中,即註冊碼的第1個字元也是變換碼的第1個字元
:0040A47D C745F000000000 mov [ebp-10], 00000000
====> 設初值
:0040A484 EB09
jmp 0040A48F
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A51D(U)
|
:0040A486 8B45F0
mov eax, dword ptr [ebp-10] ====> 取出變換次數值
:0040A489 83C001
add eax, 00000001 ====> 準備取下一個字元
:0040A48C 8945F0
mov dword ptr [ebp-10], eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A484(U)
|
:0040A48F 8B4DF0
mov ecx, dword ptr [ebp-10]
:0040A492 3B4DF8
cmp ecx, dword ptr [ebp-08] ====> 是否變換完畢
:0040A495 0F8D87000000 jnl 0040A522
====> 沒有,則繼續
:0040A49B 8B45F0
mov eax, dword ptr [ebp-10] ====> 取出變換次數值
:0040A49E 99
cdq
:0040A49F 2BC2
sub eax, edx
:0040A4A1 D1F8
sar eax, 1
====> 除以2
:0040A4A3 8945E4
mov dword ptr [ebp-1C], eax
:0040A4A6 8B55FC
mov edx, dword ptr [ebp-04] ====> 第18個註冊碼的計算值X18
:0040A4A9 F7DA
neg edx
====> 取負數,即-X18
:0040A4AB 2B55F0
sub edx, dword ptr [ebp-10] ====> -X18-變換次數
:0040A4AE 8955DC
mov dword ptr [ebp-24], edx ====> 放到[ebp-24]中
:0040A4B1 837DE400
cmp dword ptr [ebp-1C], 00000000 ====> 要變換的是否是第2、3個的註冊碼
:0040A4B5 7409
je 0040A4C0
====> 是則轉
:0040A4B7 8B45FC
mov eax, dword ptr [ebp-04] ====> 第18個註冊碼的計算值X18
:0040A4BA 0345F0
add eax, dword ptr [ebp-10] ====> X18+變換次數
:0040A4BD 8945DC
mov dword ptr [ebp-24], eax ====> 放到[ebp-24]中
40A486-40A4BD的計算:i=1~19表示註冊碼字元所在的位置,如果變換的是第2和3個的註冊碼,則[ebp-24]=-(X182),否則=(X182)
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A4B5(C)
|
:0040A4C0 6A24
push 00000024
\
:0040A4C2 8B4DDC
mov ecx, dword ptr [ebp-24] \
:0040A4C5 F7D9
neg ecx
|
:0040A4C7 51
push ecx
====> 這段跟註冊碼變換無關
:0040A4C8 E829FEFFFF call
0040A2F6 |
:0040A4CD 83C408
add esp, 00000008 /
:0040A4D0 8945E8
mov dword ptr [ebp-18], eax /
:0040A4D3 8B5510
mov edx, dword ptr [ebp+10] ====> 註冊碼地址
:0040A4D6 0355F0
add edx, dword ptr [ebp-10]
:0040A4D9 8A4201
mov al, byte ptr [edx+01] ====> 取出相應的註冊碼
:0040A4DC 8845E0
mov byte ptr [ebp-20], al
:0040A4DF 8A4DE0
mov cl, byte ptr [ebp-20]
:0040A4E2 51
push ecx
:0040A4E3 E886FCFFFF call
0040A16E ====> 進行變換
:0040A4E8 83C404
add esp, 00000004
:0040A4EB 8945EC
mov dword ptr [ebp-14], eax ====> 結果放入到[ebp-14]中
:0040A4EE 8B55EC
mov edx, dword ptr [ebp-14]
:0040A4F1 2B55DC
sub edx, dword ptr [ebp-24] ====> -[ebp-24],因此跟註冊碼所在的位置有關
:0040A4F4 8955EC
mov dword ptr [ebp-14], edx
:0040A4F7 6A24
push 00000024
====> 為什麼是24h?因為字元0~9加上A~Z正好共36個(24h)
:0040A4F9 8B45EC
mov eax, dword ptr [ebp-14]
:0040A4FC 50
push eax
:0040A4FD E8F4FDFFFF call
0040A2F6 ====> 進行變換
變換過程:如果[ebp-14]為負數,則[ebp-14]+24h,直到為非負值且小於24h;如果[ebp-14]為正數且大於等於24h,則[ebp-14]-24h直到為非負值且小於24h
:0040A502 83C408
add esp, 00000008
:0040A505 8945EC
mov dword ptr [ebp-14], eax
:0040A508 8B4DEC
mov ecx, dword ptr [ebp-14]
:0040A50B 51
push ecx
:0040A50C E8A9FBFFFF call
0040A0BA ====> 根據上面相應的計算結果確定變換程式碼
確定過程:如果[ebp-14](即ecx)的值在0-9,則轉為相應的數字,即eax=ecx+30h,否則eax=ecx+"A"-0ah=ecx+37h
:0040A511 83C404
add esp, 00000004
:0040A514 8B5508
mov edx, dword ptr [ebp+08]
:0040A517 0355F0
add edx, dword ptr [ebp-10]
:0040A51A 884201
mov byte ptr [edx+01], al ====> 變換結果放入到變換程式碼地址中
:0040A51D E964FFFFFF jmp 0040A486
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A495(C)
|
:0040A522 8BE5
mov esp, ebp
:0040A524 5D
pop ebp
:0040A525 C3
ret
總結上面的變換過程:
1. 註冊碼必須是19個字元且字元範圍在0~9和A~Z之間
2. 設註冊碼用R來表示,則R19=((R1+R2+...+R18) mod 24h)+(30h或37h),如果前面的餘數<=9則+30h,否則+37h
3. 設第18位註冊碼的變換碼為X18,則X18=R18-37h(註冊碼在A~Z)或X18=R18-30h(註冊碼在0~9),如果用筆計算一下就可知道,R18肯定是A~Z之間的字元,因此,X18=R18-37h
4. 使用者名稱和E-mail地址名的計算值=(所有字元的ascii值相加 mod 1Ah)+37h,注意:使用者名稱和E-mail地址名不能用中文字元
5. 變換程式碼的計算過程(用y表示)
(1) y1=r1
(2) 如果i=2或3, yi=((X1-(-(X182))) mod 24h)+30h或37h=(X1+X182) mod
24h)+30h或37h
(3) 如果i=4到17,yi=((X1-(X182))±n*24h)+30h或37h=(X1-X18-i+2±n*24h)+30h或37h
n=0,1,2
6. y5與使用者名稱的計算值相等,y7與E-mail地址的計算值相等,因此,y5和y7肯定是在A~Z之間
根據上面的變換過程我們可以做出這個軟體的註冊器,第一種方法是先構造一個19位的註冊碼,然後利用第5,7,18位的註冊碼再相應構造使用者名稱和E-mail地址,這種方法雖然簡單,但使用者名稱和E-mail地址可能很難看,因為我們還是喜歡使用者名稱和E-mail地址易懂的註冊碼,因此採用第二種方法
第二種方法是先構造使用者名稱和密碼,生成相應的計算值,再構造第18位的註冊碼,然後根據使用者名稱和密碼的計算值及第18位的註冊碼確定第5和第7位的註冊碼,而第1~4,6,8~17位的註冊碼隨機生成,只要符合在0~9或A~Z之間即可,最後生成第18位的註冊碼,根據這個思路,序號產生器如下(VB程式):
Private Sub Command1_Click()
Dim UserName, EmailAddress, RegCode, UserNameLong, EmailLong
Dim CheckUserCode, CheckEmailCode, RandCode, CheckCode
RegCode = "": CheckCode = ""
UserName = Text1.Text
EmailAddress = Text2.Text
UserNameLong = Len(Text1.Text)
EmailLong = Len(Text2.Text)
If UserNameLong = 0 Then
MsgBox "使用者名稱不能為空!", vbOKOnly, "請輸入使用者名稱"
Exit Sub
Else
For i = 1 To UserNameLong
CheckUserCode = CheckUserCode +
Asc(Mid(UserName, i, 1))
Next
CheckUserCode = (CheckUserCode Mod 26) + &H41
End If
If EmailLong = 0 Then
MsgBox "Email地址不能為空!", vbOKOnly, "請輸入Email地址"
Exit Sub
Else
For i = 1 To EmailLong
CheckEmailCode = CheckEmailCode
+ Asc(Mid(EmailAddress, i, 1))
Next
CheckEmailCode = (CheckEmailCode Mod 26) + &H41
End If
GetReg18:
Reg18 = MakeRndCode()
If Reg18 <= &H39 Then
GoTo GetReg18
Else
Reg18Mod = Reg18 - &H37
End If
Reg5 = (Reg18Mod + 3 + CheckUserCode - &H37) Mod &H24
If Reg5 <= 9 Then
Reg5 = Reg5 + &H30
Else
Reg5 = Reg5 + &H37
End If
If Reg5 > &H5A Then GoTo GetReg18
Reg7 = (Reg18Mod + 5 + CheckEmailCode - &H37) Mod &H24
If Reg7 <= 9 Then
Reg7 = Reg7 + &H30
Else
Reg7 = Reg7 + &H37
End If
If Reg7 > &H5A Then GoTo GetReg18
For i = 1 To 4
RandCode = MakeRndCode()
RegCode = RegCode + Chr(RandCode)
Next
RegCode = RegCode + Chr(Reg5)
RandCode = MakeRndCode()
RegCode = RegCode + Chr(RandCode)
RegCode = RegCode + Chr(Reg7)
For i = 8 To 17
RandCode = MakeRndCode()
RegCode = RegCode + Chr(RandCode)
Next
RegCode = RegCode + Chr(Reg18)
RandCode = 0
For i = 1 To 18
RandCode = RandCode + Asc(Mid(RegCode, i, 1))
Next
RandCode = RandCode Mod &H24
If RandCode <= 9 Then
RegCode = RegCode + Chr(RandCode + &H30)
Else
RegCode = RegCode + Chr(RandCode + &H37)
End If
Text3.Text = RegCode
End Sub
Function MakeRndCode()
Dim a
Randomize
NextRnd:
Do
a = Int(Rnd * 120)
Loop Until a >= &H30 And a <= &H5A
If a > &H39 And a < &H41 Then
GoTo NextRnd
End If
MakeRndCode = a
End Function
相關文章
- hellfire2000破解過程及序號產生器的編寫(上) (4千字)2001-01-19
- Kalua Cocktails 1.1完全破解,內附彙編序號產生器(用序號產生器編寫器,並有它的使用教程)
(22千字)2002-02-27AI
- 檔案密使2.0暴力破解及序號產生器的編寫―好久沒寫過東西了。 (11千字)2001-07-10
- 文書處理大師 3.0 破解~~~附序號產生器 (17千字)2002-03-24
- UltraEdit-32 8.10.1.0的破解及序號產生器的生成 (15千字)2001-05-15
- Resource
Builder 1.1.0 完全破解~~附彙編序號產生器 (10千字)2015-11-15UI
- 破解QQ圖形留言器3.0(不是OICQ圖形留言系統)及序號產生器編寫!! (6千字)2001-07-15
- Pexplorer 1.70 完全破解(KeyFile&Name+Code),附序號產生器~~~~~~~~~
(17千字)2002-04-03
- 網頁加密器(HTMLEncryptor1.1)破解及序號產生器 (1千字)2001-04-22網頁加密HTML
- 續未完成破解,寫出它的序號產生器,3k。。。 (8千字)2001-07-09
- 一個CrackMe的破解以及序號產生器的製作
(4千字)2001-08-16
- 用C++編寫序號產生器的一點技巧2015-11-15C++
- 製作mIRC6.02序號產生器(給別人寫的初學者序號產生器教材) (14千字)2015-11-15
- winzip的通用序號產生器 (2千字)2001-12-10
- winzip序號產生器 (1千字)2001-04-12
- NetTalk破解與序號產生器(高手勿進) (10千字)2001-09-20
- 美萍安全衛士V8.45序號產生器制作分析過程,及序號產生器! (11千字)2001-10-28
- 《中華壓縮 6.01》註冊碼破解及序號產生器 (14千字)2001-08-19
- 貼彩虹狗破解工具的序號產生器 (727字)2001-07-01
- 序號產生器制分析: (1千字)2001-11-19
- 破解accoustica
2.21(帶序號產生器)----讓高手見笑了:) (11千字)2002-03-31
- 音樂處理acoustica2.0註冊碼破解及序號產生器 (8千字)2002-04-06
- “我們都愛背單詞”簡易破解及序號產生器的寫法 (608字)2001-04-25
- supercapture3.0的版序號產生器!
(4千字)2002-04-23APT
- 菜鳥 學序號產生器編寫之 Android app2015-06-23AndroidAPP
- 3DAxy貪吃蛇 AxySnake 破解與序號產生器 (21千字)2015-11-153D
- EmEditor V3.29和它的序號產生器 (12千字)2015-11-15
- xplorer2之破解和序號產生器2004-12-05
- 010
Editorv1.3破解(序號產生器)2004-05-17
- 序號產生器合集2024-03-17
- SWF探索者XP 1.2(swfexplorer)破解+分析+序號產生器
(18千字)2002-04-14
- KEYGENNING4NEWBIES #7破解過程+序號產生器 (6千字)2001-08-21
- MP3 explorer 破解和序號產生器的製作2015-11-15
- Audio compositor註冊碼及序號產生器 (5千字)2002-04-06
- 我來寫UltraEdit 9.00 簡繁雙語第二版的破解過程,誰來寫序號產生器 (3千字)2002-01-26
- Gif2Swf Ver 2.1 TC20序號產生器 && MASM32序號產生器 (4千字)2001-12-10ASM
- 橋牌軟體Deep Finesse的序號產生器 (1千字)2015-11-15
- SitMan v2.0 beta版的序號產生器(TC2.0編譯) (3千字)2001-10-28編譯