摘要:本文主要從三個(gè)方面介紹了計(jì)算機(jī)軟件注冊(cè)與加密技術(shù):DOS系統(tǒng)下軟件注冊(cè)與加密,Windows系統(tǒng)軟件注冊(cè)與加密以及共享軟件網(wǎng)絡(luò)注冊(cè)方法。文中介紹的許多方法現(xiàn)在仍在沿用,也有的方法和技術(shù)早已過(guò)時(shí),但大都值得我們借鑒學(xué)習(xí)。在分析注冊(cè)加密過(guò)程和方法的同時(shí),引用了不少源代碼以突出其實(shí)現(xiàn)過(guò)程。
關(guān)鍵詞:軟件加密、軟件注冊(cè)、共享軟件
引言
隨著計(jì)算機(jī)科學(xué)與技術(shù)的發(fā)展,計(jì)算機(jī)軟件學(xué)科已經(jīng)成為計(jì)算機(jī)科學(xué)的重要組成部分,軟件產(chǎn)品也在計(jì)算機(jī)產(chǎn)品市場(chǎng)上占有重要地位。由于軟件產(chǎn)品的可復(fù)制性和可篡改性,它能很容易的被非法復(fù)制并銷售,嚴(yán)重?fù)p害了軟件設(shè)計(jì)者的合法權(quán)益。為此,軟件設(shè)計(jì)者們經(jīng)過(guò)不懈努力,精心為自己的軟件加密,以保證自己的權(quán)益不被侵犯。他們成功過(guò),但也曾對(duì)計(jì)算機(jī)安全產(chǎn)生了不良影響,有的設(shè)計(jì)者為了嚴(yán)厲打擊盜版,在程序代碼中加入“邏輯炸彈”,更有甚者,設(shè)計(jì)出帶有“自殺性”和病毒的軟件,當(dāng)發(fā)現(xiàn)有復(fù)制操作進(jìn)行時(shí),便使用這段代碼把自己銷毀并將病毒傳播出去,這些舉動(dòng)都對(duì)計(jì)算機(jī)系統(tǒng)的安全造成威脅。
要了解當(dāng)今流行的計(jì)算機(jī)軟件注冊(cè)和加密技術(shù),我們必須首先深入DOS系統(tǒng),深刻理解DOS環(huán)境下的軟件注冊(cè)和加密的原理和實(shí)現(xiàn)方法。雖然Windows已一統(tǒng)天下,DOS早已失去了它的光芒,但基于這一平臺(tái)的許多軟件設(shè)計(jì)思想都是值得借鑒的,因?yàn)樗哂?/SPAN>Windows系統(tǒng)不可替代的特性:對(duì)硬件操作更加方便,軟件的加密方法更加多樣化也更容易實(shí)現(xiàn)。Windows系統(tǒng)的出現(xiàn),又給軟件設(shè)計(jì)者們帶來(lái)了新的機(jī)遇:注冊(cè)表、動(dòng)態(tài)連接庫(kù)、多線程技術(shù)和計(jì)算機(jī)網(wǎng)絡(luò)給軟件注冊(cè)和加密提供了新的途徑。如果能將這兩種完全不同結(jié)構(gòu)的系統(tǒng)下軟件注冊(cè)加密技術(shù)結(jié)合的話,我想,所能實(shí)現(xiàn)的效果是任何一種技術(shù)都不可比擬的。
本文討論的重點(diǎn)并不在于數(shù)據(jù)的加密過(guò)程,而是在于如何充分利用操作系統(tǒng)的特性和提供的API才能使軟件加密更加安全。或者說(shuō),對(duì)于如何實(shí)現(xiàn)數(shù)據(jù)加密和通過(guò)什么途徑來(lái)實(shí)現(xiàn)軟件加密這兩個(gè)問(wèn)題,我們更加關(guān)心后者。軟件加密和數(shù)據(jù)加密不同,方法不同,目的也不同,但軟件加密離不開數(shù)據(jù)加密。
一、DOS系統(tǒng)下軟件注冊(cè)和加密技術(shù)
許多共享軟件都有這樣的特點(diǎn):使用了一段時(shí)間后,要求用戶輸入用戶名和注冊(cè)碼,用戶名由用戶自己定義,而注冊(cè)碼則需要通過(guò)付款給軟件著作人的途徑來(lái)取得,得到注冊(cè)碼后,用戶將編碼填入對(duì)話框后,軟件便能繼續(xù)使用,否則將無(wú)法運(yùn)行。這一過(guò)程是一等價(jià)交換的過(guò)程:設(shè)計(jì)者獲得其價(jià)值,用戶獲得使用價(jià)值,軟件成為商品。那么,軟件本身是如何知道用戶填入的信息是合法的呢?其實(shí)很簡(jiǎn)單:著作人和軟件本身使用了同一套注冊(cè)機(jī)制,或稱之為“協(xié)議”,用戶并不知道這一協(xié)議,所以無(wú)法破解注冊(cè)碼,只能從著作人處購(gòu)買。其實(shí)所有的注冊(cè)型軟件都有一段類似于下面的程序代碼:
PRogram MyProgram (Input, Output);
function GetKey (UserName,OtherInfo:String):KeyType;
begin
//...
end;
function Registered (UserName,OtherInfor:String;UserInput:KeyType):Boolean;
begin
if GetKey(UserName,OtherInfo)=UserInput then begin
result:=TRUE;
Exit;
end;
result:=FALSE;
end;
begin
//...
if (not Registered) then begin
ShowMessage ('Not Registered!!');
Exit;
end;
//...
end.
在這段代碼中,GetKey函數(shù)用于通過(guò)用戶的用戶名和一些其它信息生成注冊(cè)碼,Registered函數(shù)用于返回用戶是否正確注冊(cè)。上面已經(jīng)提到過(guò),軟件加密與數(shù)據(jù)加密不同,軟件加密在注重?cái)?shù)據(jù)加密算法的同時(shí),更加注重?cái)?shù)據(jù)密碼的隱蔽性。下面從三個(gè)方面來(lái)介紹DOS系統(tǒng)下的常用加密技術(shù)。
1、 使用磁盤的隱藏扇區(qū)實(shí)現(xiàn)加密
這是最古老的加密技術(shù)。仍然是上面這個(gè)問(wèn)題,為什么軟件使用一段時(shí)間以后或者是使用了多少次以后,它會(huì)提示用戶注冊(cè)?它怎么會(huì)知道用戶用了多長(zhǎng)時(shí)間或用了多少次?我們可以這樣想:在軟件被安裝程序安裝的時(shí)候,一些記錄用戶合法性和安裝時(shí)間的信息被寫到本地計(jì)算機(jī)中,在今后運(yùn)行軟件時(shí),只要判斷這些信息是否合法就可以決定是讓用戶繼續(xù)使用還是立即注冊(cè)。這種方法在一定程度上也增強(qiáng)了軟件本身的防復(fù)制性,因?yàn)閺?fù)制品在其它未正確安裝的機(jī)器上找不到合法用戶信息,也就無(wú)法正確運(yùn)行。在計(jì)算機(jī)設(shè)備中,能保存數(shù)據(jù)的最直接的地方就是磁盤,而用硬盤的隱藏扇區(qū)保存這些密碼信息又最可靠。在硬盤的數(shù)據(jù)結(jié)構(gòu)中,每個(gè)硬盤邏輯分區(qū)的第一個(gè)柱面是隱藏的,整個(gè)物理硬盤的最后幾個(gè)柱面也是隱藏的。說(shuō)它是隱藏的,也就是說(shuō),在DOS系統(tǒng)中,普通的INT 21H所提供的對(duì)磁盤讀寫的中斷調(diào)用無(wú)法管轄這部分區(qū)域,要操作這部分隱藏的磁盤空間,就必須通過(guò)INT 13H來(lái)進(jìn)行。
以下一段函數(shù)代碼實(shí)現(xiàn)了對(duì)磁盤的任何部分(包括隱藏扇區(qū))的讀寫操作,它能把一個(gè)扇區(qū)的信息讀入緩沖區(qū),也能把緩沖區(qū)中的信息存入磁盤的一個(gè)扇區(qū)。值得注意的是,這個(gè)函數(shù)只能對(duì)小于8.4GB的數(shù)據(jù)區(qū)進(jìn)行操作,大于8.4GB的數(shù)據(jù)區(qū)需要INT 13 Extension的支持,在此不多討論,有興趣的讀者可以參閱筆者所寫的《大容量硬盤的讀寫操作》。對(duì)于一般的隱藏扇區(qū)加密的實(shí)現(xiàn),使用這個(gè)函數(shù)已經(jīng)足夠了。
#include <stdio.h>
#include <dos.h>
int DiskIo (int drive,
int Operation,
unsigned int cylinder,
unsigned int head,
unsigned short sector,
unsigned char * buffer)
{
union REGS regs;
struct SREGS sregs;
regs.h.ah=operation; regs.h.al=1;
regs.x.bx=FP_OFF(buffer); sregs.es=FP_SEG(buffer);
regs.h.ch=cylinder; regs.h.cl=sector;
regs.h.dh=head; regs.h.dl=drive;
int86x(0x13,®s,®s,&sregs);
return regs.h.ah;
}
最后說(shuō)明一點(diǎn),在設(shè)計(jì)軟件中的GetKey函數(shù)時(shí),盡量使用本機(jī)的硬件信息和用戶名來(lái)生成密碼,再將其存入隱藏扇區(qū),這樣使密碼既有保密性,又有安全性。
2、 使用激光穿孔法實(shí)現(xiàn)軟件防復(fù)制加密
這種方法主要是利用程序設(shè)計(jì)中的“陷阱技術(shù)”來(lái)實(shí)現(xiàn)的。基本設(shè)計(jì)思路是這樣的:在軟盤表面穿孔,使部分扇區(qū)遭到破壞,這是物理?yè)p壞,無(wú)法用工具軟件修復(fù)。設(shè)計(jì)者在開發(fā)軟件以前,用通用的檢測(cè)工具對(duì)磁盤表面全面掃描,找到已被損壞的扇區(qū),將它們記錄下來(lái),以后設(shè)計(jì)軟件時(shí),只要讓軟件判斷這些扇區(qū)是否損壞就能判斷軟件是否已被復(fù)制。
對(duì)于生產(chǎn)少量的軟件產(chǎn)品而言,這種方法不失為一種經(jīng)濟(jì)有效的加密方法,但是如果軟件要被大量生產(chǎn),這種方法就變得更加繁雜:每次穿孔的位置不一定一樣,軟件所要判斷的扇區(qū)編號(hào)也不一樣,實(shí)現(xiàn)相當(dāng)困難,但設(shè)計(jì)思想是值得借鑒的。
3、 特殊磁道防復(fù)制加密技術(shù)
雖然激光穿孔技術(shù)能達(dá)到很好的防復(fù)制加密效果,但其實(shí)現(xiàn)過(guò)程是相當(dāng)復(fù)雜的。特殊磁道防復(fù)制加密技術(shù)實(shí)現(xiàn)簡(jiǎn)單,也能夠很好的對(duì)軟件起到加密作用。為了簡(jiǎn)單起見(jiàn),在此僅對(duì)軟盤進(jìn)行討論。
平時(shí)我們所討論的磁盤扇區(qū)都是指的數(shù)據(jù)區(qū),其實(shí)一個(gè)扇區(qū)由標(biāo)識(shí)區(qū)和數(shù)據(jù)區(qū)以及兩個(gè)間隙組成,一些磁道(柱面)的ID信息被保存在非數(shù)據(jù)區(qū)中。在DOS系統(tǒng)啟動(dòng)的時(shí)候,軟盤磁盤基數(shù)表被裝載到起始地址為0000:0525的內(nèi)存單元中,INT 13H的許多操作都是根據(jù)這一基數(shù)表來(lái)確定扇區(qū)大小的。那么,只要我們修改磁盤基數(shù)表,再用普通的INT 13H來(lái)操作磁盤,就能很容易的將軟件密鑰寫到磁盤扇區(qū)間隙處。一般情況下,對(duì)于這種特殊扇區(qū),磁盤控制器無(wú)法在磁盤上寫出,這樣,一般的復(fù)制程序也就無(wú)法將其復(fù)制,但在被加密的軟件程序中可以將間隙處的密鑰作為特殊扇區(qū)的一部分讀出,判斷密鑰信息就可以確定軟件是否已被復(fù)制。
以下是采用這種方法讀取一個(gè)扇區(qū)長(zhǎng)為4096B的數(shù)據(jù)區(qū)的例子,讀取的是軟盤的0面0道,讀出的信息被保存在DS段偏移量為1000H的內(nèi)存單元中。
C:/WINDOWS>debug
-e0000:0525
0000:0525 02.05
-a100
1288:0100 mov ax,201
1288:0103 mov bx,1000
1288:0106 mov cx,0
1288:0109 mov dx,0
1288:
1288:010E int 3
1288:
-g=100
特殊磁道加密是這樣實(shí)現(xiàn)的:INT 13H AH=05H功能是根據(jù)BX所指向的內(nèi)存單元的參數(shù)來(lái)對(duì)磁盤進(jìn)行格式化的。上面已經(jīng)提到,每個(gè)扇區(qū)都有一個(gè)ID,ID是由柱面號(hào)、磁頭號(hào)和扇區(qū)字節(jié)長(zhǎng)度組成,那么只要修改ID參數(shù),并用這種奇特的參數(shù)格式化磁盤,就會(huì)產(chǎn)生特殊磁道。剩下的工作和對(duì)特殊扇區(qū)的操作相同:將密鑰寫入特殊磁道,就能實(shí)現(xiàn)軟件防復(fù)制。下面是一個(gè)對(duì)360K、DSDD磁盤磁道格式化的C語(yǔ)言函數(shù),其中trktbl數(shù)組存放的就是磁盤扇區(qū)的ID參數(shù)。
int fmt_trk (int dsk, int trk, int head)
{
union REGS regs;
struct SREGS sregs;
char trktbl[36];
int i;
for (i=0;i<9;i++) {
trktbl[i*4] = trk;
trktbl[i*4+1] = head;
trktbl[i*4+2] = i;
trktbl[i*4+3] = 2;
}
regs.h.ah=0x05; regs.h.ch=trk;
regs.h.dh=head; regs.h.dl=dsk;
regs.x.bx=FP_OFF(trktbl); sregs.es=FP_SEG(trktbl);
int86x (0x13, ®s, ®s, &sregs);
return (regs.h.ah);
}
二、Windows系統(tǒng)下軟件注冊(cè)加密技術(shù)
1、利用Windows注冊(cè)表實(shí)現(xiàn)軟件注冊(cè)加密
相信大多數(shù)軟件都是采用這種方法來(lái)實(shí)現(xiàn)注冊(cè)功能的。Windows系統(tǒng)注冊(cè)表信息量相當(dāng)大,幾乎所有Windows系統(tǒng)和計(jì)算機(jī)系統(tǒng)配置信息都保存在注冊(cè)表中。如果軟件密鑰被寫入注冊(cè)表,那么尋找密鑰保存位置無(wú)異于海底撈針,不采用一定的技術(shù)(如線程跟蹤等)是無(wú)法得到密鑰的。
Windows系統(tǒng)注冊(cè)表有六個(gè)主鍵:HKEY_CLASS_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、HKEY_USERS、HKEY_CURRENT_CONFIG和HKEY_DYN_DATA。每個(gè)主鍵下面又分若干個(gè)子鍵,每個(gè)子鍵下又可新建子鍵和項(xiàng),整個(gè)注冊(cè)表呈樹狀結(jié)構(gòu)。每個(gè)項(xiàng)都有名稱和值,值可以是二進(jìn)制、十進(jìn)制、十六進(jìn)制和字符串型。
用程序?qū)崿F(xiàn)注冊(cè)表的操作是相當(dāng)簡(jiǎn)便的。以下Delphi程序段用以在HKEY_CURRENT_USER的子鍵Software下創(chuàng)建一個(gè)名為Arcobet的子鍵,并將字符串“ChenQingyang”寫入該字符串中。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Registry, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var regs:TRegistry;
begin
regs:=TRegistry.Create;
regs.RootKey := HKEY_CURRENT_USER;
if (not regs.OpenKey('Software/Arcobet',False)) then
regs.CreateKey ('Software/Arcobet');
regs.WriteString('UserName','ChenQingyang');
regs.CloseKey;
regs.Destroy;
end;
end.
2、Windows系統(tǒng)下的特殊磁道法
這種方法的基本原理同上述DOS下的特殊磁道法原理相同,但必須注意的是:在32bit application中直接使用INT 13H,Windows系統(tǒng)會(huì)彈出保護(hù)性錯(cuò)誤的對(duì)話框,禁止程序的繼續(xù)執(zhí)行。
解決這種問(wèn)題的基本方法是采用虛擬設(shè)備驅(qū)動(dòng)程序“VWIN32.VxD”,而使用該VxD又是通過(guò)DeviceIoControl來(lái)實(shí)現(xiàn)的,它能完成INT 13H、INT 25H、INT 26H的各種功能。通過(guò)CreateFile打開VWIN32.VxD后獲得控制句柄,進(jìn)而執(zhí)行各種控制命令。打開VWIN32.VxD格式如下:
HANDLE hDevice=CreateFile (“////.//VWIN32”, GENERIC_WRITE|GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
在所有操作完成后,應(yīng)使用CloseHandle (hDevice)來(lái)關(guān)閉打開的VWIN32.VxD。
如何使用這種方法讀寫磁盤在此不作討論,請(qǐng)讀者自己參考有關(guān)文獻(xiàn)。
三、共享軟件網(wǎng)上注冊(cè)方法簡(jiǎn)介
隨著Internet的發(fā)展,共享軟件也隨之出現(xiàn)。共享軟件允許用戶對(duì)軟件試用,并通過(guò)Internet網(wǎng)上注冊(cè)的途徑來(lái)購(gòu)買軟件。共享軟件有一個(gè)最大的好處就是其可試用性,通過(guò)用戶的免費(fèi)試用,能及時(shí)的將使用結(jié)果反饋給軟件作者,作者便可以根據(jù)這些反饋信息對(duì)軟件的結(jié)構(gòu)和功能改進(jìn)。可以說(shuō),共享軟件給用戶和作者提供了更為廣泛的交流空間。另一方面,軟件購(gòu)買也變的更加簡(jiǎn)單,大大減少了軟件在市場(chǎng)上的周轉(zhuǎn)期,使軟件版本的更新也更快。
許多優(yōu)秀的軟件如《Windows優(yōu)化大師》等在被用戶使用了一段時(shí)間后都會(huì)要求用戶注冊(cè)方能繼續(xù)使用。此時(shí),用戶應(yīng)根據(jù)界面提示填寫好用戶名,程序會(huì)自動(dòng)生成一個(gè)序列號(hào),只要將這個(gè)序列號(hào)和注冊(cè)費(fèi)用一起郵寄給軟件作者,便可以得到注冊(cè)碼,最后把注冊(cè)碼填入軟件指定的位置并確認(rèn)后,共享軟件注冊(cè)過(guò)程就完成了。
為了方便用戶的注冊(cè),許多共享軟件網(wǎng)站都有代理注冊(cè)的服務(wù),其作用相當(dāng)于用戶和作者之間的一座橋梁,幫助雙方方便的完成注冊(cè)過(guò)程。用戶只需要將序列號(hào)和注冊(cè)費(fèi)上交到網(wǎng)站,網(wǎng)站定期地將用戶名單、序列號(hào)和注冊(cè)費(fèi)轉(zhuǎn)交給作者,作者根據(jù)網(wǎng)站發(fā)送的信息生成每個(gè)用戶的注冊(cè)碼后反饋給網(wǎng)站,最后網(wǎng)站再將獲得的注冊(cè)碼分發(fā)到每個(gè)用戶手里。
結(jié)論
軟件加密注冊(cè)方法還有很多,以軟件手段加密的比如CRC錯(cuò)誤校驗(yàn)法、弱位法、硬盤鎖、軟件狗等,以硬件手段加密的有硬件狗等,在此不一一說(shuō)明。總之,只要我們能夠好好的利用操作系統(tǒng)給我們帶來(lái)的程序資源和接口,我們就能夠利用這些接口和特性設(shè)計(jì)出很好的注冊(cè)加密方法。有興趣的讀者可以按照本文介紹的方法或者參考其它文獻(xiàn)動(dòng)手試一試,相信這樣做能給你帶來(lái)更大的收獲。
參考文獻(xiàn)
1、《軟件加密與計(jì)算機(jī)安全技術(shù)》孫兆林 主編 中國(guó)水利出版社 2001年9月
2、《DOS程序員參考手冊(cè)》Terry Dettmann 著 清華大學(xué)出版社 1996年1月
3、《For Win9X系統(tǒng)下額外磁道防復(fù)制技術(shù)》 劉興平(《電腦編程技巧與維護(hù)》2000-5)
4、《Windows系統(tǒng)注冊(cè)表完全精通》 電腦愛(ài)好者雜志社 2001年5月
5、《加密解密方法與實(shí)例》e-Age Technology&Development 北京騰圖電子出版社
6、《深入DOS編程》 求伯君 著 1993年
7、《Microsoft Software Developer Network(MSDN)》Microsoft Press, July 2001
8、《利用互斥磁盤鎖定保護(hù)磁盤數(shù)據(jù)》 江天送 (《電腦編程技巧與維護(hù)》2000-10)
9、《DOS6.22內(nèi)核分析與內(nèi)存管理技術(shù)》 肖金秀 著 中國(guó)大地出版社 1998年1月
10、CSDN網(wǎng)站:http://www.csdn.net
11、DDCOPY:硬盤全盤復(fù)制軟件:http://ddcopy.yeah.net新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注