這個(gè)注冊(cè)機(jī)編寫(xiě)器以前一直是我自己為寫(xiě)注冊(cè)機(jī)而編寫(xiě)的,通過(guò)它只要略有匯編基礎(chǔ)很快就能寫(xiě)出一個(gè)注冊(cè)機(jī)。而不需要再過(guò)多的了解程序的指令算法。 整個(gè)程序體實(shí)際上只是我用匯編寫(xiě)的一個(gè)模板。所以大家也可以在其中自定義自己的界面和提示信息?梢杂肰C++或BC++等資源編輯工具自行修改key1.res資源文件,但請(qǐng)不要修改它們對(duì)應(yīng)的ID號(hào)。
點(diǎn)擊此下載例子程序,主要用來(lái)舉例說(shuō)明這個(gè)程序的使用(我先假設(shè)自己并不太懂Win32匯編)。
下載Keymaker:http://elephantinaurance.com/soft/8512.html
通過(guò)動(dòng)態(tài)調(diào)試或反匯編例子程序可以得到以下注冊(cè)碼的計(jì)算過(guò)程:
xxxx:00401077 CALL GetCommandLineA
xxxx:0040107C CMP BYTE PTR [EAX],22
xxxx:0040107F JNZ 401082
xxxx:00401081 INC EAX
xxxx:00401082 MOV CX,WORD PTR [EAX]
xxxx:00401085 MOV WORD PTR [0040306C],CX
xxxx:0040108C MOV WORD PTR [0040306E],5C
xxxx:00401095 PUSH 0
xxxx:00401097 PUSH 0
xxxx:00401099 PUSH 0
xxxx:0040109B PUSH 0
xxxx:0040109D PUSH DWORD 00403058
xxxx:004010A2 PUSH 0
xxxx:004010A4 PUSH 0
xxxx:004010A6 PUSH DWORD 0040306C
xxxx:004010AB CALL GetVolumeInformationA
………… …………
………… …………
xxxx:0040111E MOV EAX,1
xxxx:00401123 CPUID
xxxx:00401125 MOV ECX,DWORD PTR [00403058]
xxxx:0040112B XOR EDX,EDX
xxxx:0040112D MUL ECX
xxxx:0040112F ADD EAX,EDX
xxxx:00401131 PUSH EAX
xxxx:00401132 PUSH DWORD 0040303E ; 在這里下D 40303E可以看到數(shù)據(jù)窗口中顯示為“%1X”
xxxx:00401137 PUSH DWORD 0040305C
xxxx:0040113C CALL wsprintfA
對(duì)于以上的指令并不需要過(guò)多的了解它在干什么,只要將其中的每個(gè)地址改成一個(gè)變量地址的聲明,然后再原封不動(dòng)的抄到注冊(cè)機(jī)編寫(xiě)器的代碼窗口中即可。
這是寫(xiě)好的聲明:
a1 dd 0 | ; 這是一個(gè)雙字的內(nèi)存空間,對(duì)應(yīng)于上面的403058。 ;(因?yàn)?0109D處的指令是DWORD 403058,所以用dd,如果是WORD就用dw,如果是BYTE就用db) |
a2 dd 0 | ; 對(duì)應(yīng)于上面的40306C |
a3 db "%1X",0 | ; 對(duì)應(yīng)于上面的40303E指向的字符串 |
a4 db 20 dup (0) | ; 這是20個(gè)字節(jié)的內(nèi)存空間,用來(lái)存放輸出的注冊(cè)碼,對(duì)應(yīng)于上面的40305C |
輸入如圖所示:
這是寫(xiě)好的程序代碼:
CALL GetCommandLineA CMP BYTE PTR [EAX],22h | ; 后面加h表示是十六進(jìn)制 |
JNZ n1 | |
INC EAX | |
n1: | |
MOV CX,WORD PTR [EAX] | |
MOV WORD PTR a2,CX | |
MOV WORD PTR a2+2,5Ch | |
PUSH 0 | |
PUSH 0 | |
PUSH 0 | |
PUSH 0 | |
LEA EAX,a1 | ; 令EAX指向a1 |
PUSH EAX | |
PUSH 0 | |
PUSH 0 | |
LEA EAX,a2 | |
PUSH EAX | ; 令EAX指向a2 |
CALL GetVolumeInformationA | ; 當(dāng)然這幾條語(yǔ)句也可以直接寫(xiě)成 invoke GetVolumeInformationA,addr a2,0,0,addr a1,0,0,0,0 的形式 |
MOV EAX,1 | |
CPUID | |
MOV ECX,a1 | |
XOR EDX,EDX | |
MUL ECX | |
ADD EAX,EDX | |
PUSH EAX | |
LEA EAX,a3 | ; 令EAX指向a3,也就是指向字符“%1X”。 |
PUSH EAX | |
LEA EAX,a4 | |
PUSH EAX | |
CALL wsprintfA | |
LEA EAX,a4 | ; 令EAX指向a4。因?yàn)槌绦蜃詈箫@示的就是EAX寄存器所指向的內(nèi)存地址的數(shù)據(jù)。 |
輸入如下圖所示:
可以看到這與上面的反匯編代碼基本相同。點(diǎn)擊編譯就可以很容易的得到一個(gè)注冊(cè)機(jī)了。
生成的注冊(cè)機(jī)如下圖所示(這只是我寫(xiě)的外觀,你也可以自行修改):
需要說(shuō)明的是因?yàn)檫@只是我寫(xiě)的一個(gè)模板,所以我也在程序中使用了幾個(gè)變量。
請(qǐng)不要再重復(fù)聲明:hCursorHandle、hInstance、hIcon、hTempEbp、hInput、hMode以免出錯(cuò)。
還有就是你一定要在指令結(jié)束時(shí)令EAX指向正確的注冊(cè)碼地址。
這種算注冊(cè)碼的方法不是直接從用戶所輸入的序列號(hào)來(lái)計(jì)算注冊(cè)碼的,所以并不適用于所有情況。有時(shí)我們可能需要根據(jù)用戶所填入的序列號(hào)來(lái)計(jì)算注冊(cè)碼。考慮到這種情況所以我在程序初使時(shí)令EAX指向第一個(gè)編輯框(也就是輸入序列號(hào)的窗口)收到用戶輸入的數(shù)據(jù),令EBX指向第二個(gè)編輯框收到用戶輸入的數(shù)據(jù),令ECX指向第三個(gè)編輯框收到用戶輸入的數(shù)據(jù)。你如果要對(duì)用戶輸入的序列號(hào)或用戶名等信息進(jìn)行操作,那么可以就對(duì)EAX、EBX、ECX進(jìn)行操作。
下面的代碼是本例根據(jù)用戶所填入的序列號(hào)來(lái)計(jì)算注冊(cè)碼的方法:
MOV ECX,EAX | ; EAX指向用戶輸入的八位序列號(hào),現(xiàn)在暫將它移動(dòng)到ECX寄存器 |
XOR EBX,EBX | ; 以下是一段典型的將內(nèi)存中的ASCII碼轉(zhuǎn)換為十六進(jìn)制代碼。 |
n1: | |
MOVZX EAX,BYTE PTR [ECX] | |
OR AL,AL | |
JZ n3 | |
CMP AL,3Ah | |
JC n2 | |
SUB AL,7 | |
n2: | |
SUB AL,30h | |
SHL EBX,4 | |
ADD EBX,EAX | |
INC ECX | |
JMP n1 | |
n3: | ; 我想以上的一段代碼應(yīng)該懂匯編就能寫(xiě)的出(如果不是很明白,那么你對(duì)我編寫(xiě)好的注冊(cè)機(jī)用TRW調(diào)試一次就知道了)。 |
PUSH EBX | ; 最后的十六進(jìn)制結(jié)果都保存在寄存器EBX中 ; 將EBX入棧,這是為了將EBX寄存器的數(shù)據(jù)保存起來(lái)。因?yàn)榻?jīng)過(guò)CPUID這個(gè)指令后EBX的值將被修改。然后后面就和上面一樣照抄程序中的指令。以下計(jì)算注冊(cè)碼的方法很簡(jiǎn)短。但在實(shí)際的破解過(guò)程中,程序的算法可能會(huì)相當(dāng)復(fù)雜。這就需要你通過(guò)調(diào)試或反匯編將關(guān)鍵的運(yùn)算指令都找出來(lái),再寫(xiě)進(jìn)來(lái)。 |
MOV EAX,1 | |
CPUID | |
POP ECX | ; 恢復(fù)EBX的值到ECX寄存器 |
XOR EDX,EDX | |
MUL ECX | |
ADD EAX,EDX | |
PUSH EAX | |
LEA EAX,a3 | ; 令EAX指向a3,也就是指向字符“%1X”。 |
PUSH EAX | |
LEA EAX,a4 | |
PUSH EAX | |
CALL wsprintfA | |
LEA EAX,a4 | ; 令EAX指向a4。因?yàn)槌绦蜃詈箫@示的就是EAX寄存器所指向的內(nèi)存地址的數(shù)據(jù)。 |
下圖分別是采用方案二和方案三編譯后的窗口界面:
如果你不采用這種方法編寫(xiě)那么也可以使用程序中的另一個(gè)功能“另類注冊(cè)機(jī)”。它和CrackCode2000一樣,也是通過(guò)攔截程序指令并顯示出注冊(cè)碼。 我之所以再寫(xiě)一個(gè)是因?yàn)橐郧暗腃rackCode2000提供的攔截選項(xiàng)非常有限,而且也不對(duì)Wide格式(出現(xiàn)在VB程序中用00將ASCII碼分隔開(kāi))提供支持,還有一個(gè)毛病是在有些程序中會(huì)出現(xiàn)莫名的非法操作或無(wú)法獲得注冊(cè)碼的情況(就好比這個(gè)例子程序)。 另外它的界面也太簡(jiǎn)陋了,只是一個(gè)消息框。所以我用匯編寫(xiě)了這個(gè)另類注冊(cè)機(jī)非常小巧,它最多可以設(shè)置100個(gè)斷點(diǎn)(其實(shí)可以更多,但好象沒(méi)這個(gè)必要),以及在每個(gè)斷點(diǎn)處中斷多少次,如下圖所示:
對(duì)于以上界面的說(shuō)明:程序名稱和中斷地址的設(shè)置,這個(gè)我想用不著多說(shuō),會(huì)破解的人都懂。 而獲取注冊(cè)碼的方式上需要說(shuō)明一下,我是這樣考慮的:寄存器方式-因?yàn)樽?cè)碼可能是會(huì)放在寄存器中比較,并且可能經(jīng)過(guò)十進(jìn)制或十六進(jìn)制的轉(zhuǎn)換, 所以就提供了一個(gè)寄存器方式及十進(jìn)制或十六進(jìn)制的選項(xiàng)。 內(nèi)存方式-是指:如設(shè)置為EDX,即指注冊(cè)碼保存在EDX所指向的內(nèi)存地址中(而不是寄存器里)這樣就為獲取注冊(cè)碼提供了更多的選擇。
可以自定義在彈出的對(duì)話框中將顯示的主頁(yè)、郵件和窗口標(biāo)題,如下圖所示:
生成的注冊(cè)機(jī)有二個(gè)可選界面如下圖所示:
需要說(shuō)明的一點(diǎn)是這個(gè)對(duì)話框只在攔截成功的時(shí)候出現(xiàn)。
除此之外還有一個(gè)制作破解補(bǔ)丁的附加工具,制作界面如圖所示。
這是完成界面。