現有軟件加密基本都是採用各種硬件系列號作為加密依據,實現的是一機一碼制,在採用硬件系列號作為加密依據之前,先要了解下各種硬件系列號的情況。這樣有利於選擇軟件加密依據,防止註冊碼可以在多台計算機上使用。
獲取硬盤系列號
硬盤系列號是生產廠家在硬盤出廠之前就寫入到硬盤中不可以修改的系列號,也就是所謂的出廠系列號或是物理系列號,該系列號一旦寫入就不可以進行修改,並且是唯一的,但有些硬盤廠家生產的硬盤沒有這個系列號,也就是說系列號為空。硬盤出廠系列號與硬盤分區卷的系列號的區別在於:卷的系列號可以修改,並且只要一重新格式化,該系列號就會改變;而硬盤出廠系列號是不可修改的,格式化以後系列號不會被改變。
如果採用分區卷的系列號作為加密依據,其一,只要購買一個註冊碼,其他的計算機只要修改卷的系列號就可以成為軟件的正式用戶;其二,如果用戶重新格式化過分區,那麼就要重新給用戶發送新的系列號,因為沒有確切的證據,也不知道用戶是否真的格式化過分區還是使用另外的計算機的分區系列號來獲取註冊碼。所以為了避免出現一碼多機可用和引起不必要的麻煩,建議在實際加密過程中不要使用硬盤卷的分區系列號作為加密依據,而應該採用硬盤出廠系列號作為軟件的加密依據。
雖然不使用卷的系列號作為加密依據,但這裡也來看看怎麼獲取磁盤分區卷的系列號?其實很簡單,只要調用 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地址可以更改,以硬盤出廠序列號作為加密依據是比較好的選擇。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/281021.html
微信掃一掃
支付寶掃一掃