現有軟件加密基本都是采用各種硬件系列號作為加密依據,實現的是一機一碼制,在采用硬件系列號作為加密依據之前,先要了解下各種硬件系列號的情況。這樣有利于選擇軟件加密依據,防止注冊碼可以在多臺計算機上使用。
獲取硬盤系列號
硬盤系列號是生產廠家在硬盤出廠之前就寫入到硬盤中不可以修改的系列號,也就是所謂的出廠系列號或是物理系列號,該系列號一旦寫入就不可以進行修改,并且是唯一的,但有些硬盤廠家生產的硬盤沒有這個系列號,也就是說系列號為空。硬盤出廠系列號與硬盤分區卷的系列號的區別在于:卷的系列號可以修改,并且只要一重新格式化,該系列號就會改變;而硬盤出廠系列號是不可修改的,格式化以后系列號不會被改變。
如果采用分區卷的系列號作為加密依據,其一,只要購買一個注冊碼,其他的計算機只要修改卷的系列號就可以成為軟件的正式用戶;其二,如果用戶重新格式化過分區,那么就要重新給用戶發送新的系列號,因為沒有確切的證據,也不知道用戶是否真的格式化過分區還是使用另外的計算機的分區系列號來獲取注冊碼。所以為了避免出現一碼多機可用和引起不必要的麻煩,建議在實際加密過程中不要使用硬盤卷的分區系列號作為加密依據,而應該采用硬盤出廠系列號作為軟件的加密依據。
雖然不使用卷的系列號作為加密依據,但這里也來看看怎么獲取磁盤分區卷的系列號?其實很簡單,只要調用 API函數 GetVolumeInformation 就可以得到磁盤分區卷的系列號。 API 函數 GetVolumelnformation 在 MSDN 中的函數原型如下:
?BOOL GetVolumelnformation(
?LPCTSTR lpRootPathName, //指向文件系統根的路徑字符串
?LPTSTR IpVolumeNameBuffer, //接收返回的卷名的緩沖區
?DWORD nVolumeNameSize, //上述緩沖區的長度
?LPDWORD pVolumeSerialNumber, //接收卷序列號的整數變量的地址
?LPDWORD pMaimumComponenilength, //接收卷上最大文件路徑長度的整數變量的地址
?LPDWORD IpFileSystemFlagx, 1/接收卷文件系統標志的整數變量的地址
???????? LPTSTR ipFilSystemNameBufer, //接收返回的卷的文件系統名的緩沖區0?
DWORD nFileSystemNameSsize //上述緩沖區的長度?
)
?
示例代碼如下:
//獲取指定磁盤分區的卷系列號
?function GetDiskvo1 (Driver:String): DWORD;?
?var
?volumeSerialNumber : DWORD;
MaximumComponentLength : DWORD;
FileSystemFlags :DWORD;
?beqin
?if Driver length(Driver)] =':' then
Driver :=Driver + ‘\’
GetVolumeInformation(PChar (Driver), nil,0,@VolumeSerialNumber,
?MaximumComponentlength,
?FileSystemFlags, ?nil,0);
?Resul t:= (VolumeSeria1Number);
?end;
?procedure TForm1.Button1click(sender; Tobject);? ??
?begin
?Label1.caption:-IntToHex(GetDiskVo1('c:V9),8);
end;
獲取硬盤的出廠系列號還要考慮到硬盤的接口類型,在這里只介紹 IDE 接口的和 SCSI 接口的。首先看看要獲取硬盤系列號所需要的幾個 API 函數:
?BOOL DeviceloControl(
HANDLE hDevice,?? //設備句柄
DWORD dwloControlCode, //控制代碼
LPVOID IpInBufer, //指向包含操作所需的數據的緩沖區指針
DWORD nInBufferSize, //lpInBuffer 參數指向的緩沖區的大小
LPVOID IpOutBufer, //指向用來接收輸出數據的緩沖區
DWORD nOuBuferSize, //指向用來接收輸出數據的緩沖區
?LPDWORD ipBytesRethurned //指向變量用于返回緩沖區數據的數量
?LPOVERLAPPED IpOverlaped //指向 OVERLAPPED 結構
);
HANDLE CreateFile(
?LPCTSTR IpFileName, //指向文件名
?DWORD dwDesiredAccess, //訪問模式(讀或寫)
?DWORD dwShareMode, //共享模式
?LPSECURITY_ATTRIBUTES ipSecurityAttributes,
//指向安全屬性
?DWORD dwCreationDisposition, //如何創建文件
?DWORD dwFlagsAndAtributes, //文件屬性
?HANDLE hTemplateFile //文件模板句柄
獲取硬盤出廠系列號的完整示例代碼如下:
?unit DiskserialUnit;
?interface
?uses
?Windows; SysUtils;
?function GetHddserial: string;
?implementation
?function GetIdeDiskserialNumber: String;
type
?TSrbIoControl = packed record
HeaderLength :ULONG;
?Signature? Array[0..7] of Char;
?Timeout? ULONG;
Controlcode:ULONG;
ReturnCode? ULONG;
?Length :ULONG;
?end;
?SRB_IO_CONTROL = TSrbIoControl;
PSrbIoControl =^TSrbIoControl;
?TIDERegs = packed record bFeaturesReg :Byte;
?bsectorCountReg :Byte;
?bsectorNumberReg : Byte;
bcylLowReg :Byte;
?bcylHighReg :Byte;
?bDriveHeadReg :Byte;
bcommandReg: Byte;
?bReserved:Byte;
?end;
IDEREGS=TIDERegs;
PIDEREGS=^TIDERegs;
?TsendcndInParams = packed record
?CBuffersize : DWORD;
?irDriveRegs:TIDERegs;
bdriveNumber : Byte;
bReserved:Arraylo..2] of byte;
dwReserved:Array10..31 of DWORD;
bBuffer : Array[0..0] of Byte
?end;
?SENDCMDINPARAMS= TSendCmdInParams; PSendCmdInParams=TSendCmdInParams;
?TIdSector = packed record
?wGenConfig :Word;
?wNumCyls : Word;
?wReserved :Word;
?wNumHeads :Word;
?wBytesPerTrack: Word;
?wBytesPerSector :Word;
?wSectorsPerTrack : Word;
?wVendorUnique :Array10..2] of word;
?sSerialNumber : Arraylo..19] of Char;
?WBufferType? :Word;
wBuffersize :Word;
?wEccsize? :Word;
sFirmwareRev :Array[0..7] of char;
sMode1Number : Array[0..39] of Char;
WMoreVendorUnique :Word;
wDoublewordIo:Word;
?wcapabilities :Word;
?wReserved1 : Word; ?
?wPIOTiming:word;
WDMATiming:word;
?wBS: Word1;
?WNumcurrentcyla:Word;
?wNumcurrentHeads:Word;
wNumcurrentSectorsPerTrack:Word;
?ulCurrentSectorCapacity? : ULONG;
ulTotalAddressableSectors:ULONG:
wSingleWordDMA:Word;
sMultiWordDMA:Word;
bReserved:Array[0..127] of byte;
end;
PIdsector = ^TIdSector;
const
?IDEID_FUNCTION -=SECI
?IDENTIFY BUFFER SIZE =512;
?DFP RECEIVE DRIVE DATA? =$0007c088:
?IOCTL SCSI MINIPORT =$0004d008;
?IOCTL SCSI MINIPORT_IDENTIFY =$001b0501;
?Datasito =sizeof(TSendomdInParams)-1+IDENTIFY BUFFER_SIZE; ButfferSize=Sizeof(SRB_IO_CONTROL)+DataSize;
W9xbuffersize=IOENTIFYBUFER_SIZE+16;
?var
?hDevice : THandler
?cbbytenReturned : DWORD;
?pInData: PSendCmdInParams;
?poutData : Pointer; // PSendCndInParama;
Bufter : Array[0..Buffersize-1] of Byte;
srbcontrol : Tsrblocontrol absolute buffers;
?procedure Changonyteorder( var patat size t Integer )
?var
ptr : PChar;
?i :Integer;
?c : Char;
?begin
//判斷操作系統
//獲取SCSI接口句柄
?end;
function ScsiHddSerialNumber:String;
{$ALIGN ON}
Type
end;
begin
end;
function GetHddSerial:string
var
? NumTry:Byte;
FinalStr:String;
begin
NumTry := 1;
Repeat
? Case NumTry of
1:FinalStr:= ScsiHddSerialNumber;
2:FinalStr:= GetIdeDiskSerialNumber;
3:FinalStr:=’Error’;
End;
Inc(NumTry);
Until(FinalStr <> ‘’) or (NumTry > 4);
Result := FinalStr;
end;
end.
在實際加密過程中,不建議使用CPU序列號和網卡的MAC地址作為加密依據,因為相同型號的CPU的序列號相同,并且,MAC地址可以更改,以硬盤出廠序列號作為加密依據是比較好的選擇。
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。