WIN下動態註冊碼實現方法 (轉)

worldblog發表於2007-12-15
WIN下動態註冊碼實現方法 (轉)[@more@]

所謂的動態註冊碼就是在不同的機器執行時註冊碼將不同。此做法的好處在於不可能以同一註冊碼註冊不同機器上的軟體。這樣就提高了軟體的保密性。這種方法已被普遍運用,下面就以俺用C++ Builder寫的一個為列,介紹一下實現原理。
WIN下動態註冊碼實現方法:

作者:

  所謂的動態註冊碼就是軟體在不同的機器執行時註冊碼將不同。此做法的好處在於不可能以同一註冊碼註冊不同機器上的軟體。這樣就提高了軟體的安全保密性。這種方法已被普遍運用,下面就以俺用C++ Builder寫的一個程式為列,介紹一下實現原理。

   獲取資訊用於註冊,不同廠商的CPU其資訊也將不同,下面只用了一個修訂本ID,可以考慮將結構中所有資訊做運算。

   獲取CPU資訊用WIN的GetSystemInfo。 該函式執行後將填充SYSTEM_INFO結構。其結構如下:

VOID GetSystemInfo(

LPSYSTEM_INFO lpSystemInfo // address of system information structure

);

Parameters

lpSystemInfo

Points to a SYSTEM_INFO structure to be filled in by this function.

typedef struct _SYSTEM_INFO { // sinf

union {

D dwOemId;

struct {

WORD wProcessorArchitecture;

WORD wReserved;

};

};

DWORD dwPageSize;

LPVOID lpMinimumApplicationAddress;

LPVOID lpMaximumApplicationAddress;

DWORD dwActiveProcessorMask;

DWORD dwNumberOfProcessors;

DWORD dwProcessorType;

DWORD dwAllocationGranularity;

WORD wProcessorLevel;

WORD wProcessorRevision; //我們所用到的

} SYSTEM_INFO;

   當格式化時會隨機填寫邏輯硬碟的序列號,因是隨機填寫相同的序列號的可能性微乎其微。再加上CPU資訊 和最後對兩個值做的運算,這樣就可以實現在不同機上得到不同的註冊號。用WINAPI的GetVolumeInformation函式得到邏輯序列號,其原形如下:

   BOOL GetVolumeInformation(

LPCTSTR lpPathName, // address of root directory of the file system LPTSTR lpVolumeNameBuffer, // address of name of the volume

DWORD nVolumeNameSize, // length of lpVolumeNameBuffer

LPDWORD lpVolumeSerialNumber, // address of volume serial number

LPDWORD lpMaximumComponentLength, // address of system's maximum

filename length

LPDWORD lpFileSystemFlags, // address of file system flags

LPTSTR lpFileSystemNameBuffer, // address of name of file system

DWORD nFileSystemNameSize // length of lpFileSystemNameBuffer

);

   從上看我們只關心第四個引數返回邏輯硬碟序列號。我們將主功能做成DLL形式在應用程式中 這樣使用起來即方便,又提高了安全性。具體程式如下:

.H

private: // User declarations

DWORD (WINAPI *GetCurrentHostSeriaNumber)(void); //宣告函式指標

.CPP檔案

HINSTANCE DLLinst=LoadLibrary("GetSeria"); //動態呼叫DLL檔案

if(DLLinst) { GetCurrentHostSeriaNumber=(DWORD(WINAPI *)(void)) GetProcAddress(DLLinst,"GetCurrentHostSeriaNumber"); //獲取DLL中的函式 if(GetCurrentHostSeriaNumber)

{

DWORD Rember=GetCurrentHostSeriaNumber(); //並返回註冊碼 if(String(RegNumber)==Edit1->Text) //與輸入進行比較

ShowMessage("註冊碼正確");

else ShowMessage("註冊碼錯誤");

}

else ShowMessage("DLL中函式錯誤");

} else ShowMessage("GetSeria.dll不在當前目錄下");

.DLL檔案

extern "C" __declspec(dllexport) DWORD WINAPI GetCurrentHostSeriaNumber(void); 以標準C方式宣告函式呼叫方法

int WINAPI DllEntryPoint(HINSTANCE, unsigned long , void*)

{

return 1;

}

DWORD WINAPI GetCurrentHostSeriaNumber(void)

{

SYSTEM_INFO info;

DWORD SeriaNumber=NULL;

DWORD Register=NULL;

GetSystemInfo(&info); //呼叫函式填SYSTEM_INFO結構 GetVolumeInformation("C:",NULL,NULL,&SeriaNumber,NULL,NULL,NULL,NULL)

; //獲取C盤序列號

Register=SeriaNumber+info.wProcessorRevision;

Register=Register^7609926; //相加後最異或運算

return Registet;

}

   此程式雖是一個簡單的DEMO,但稍微加工就可以為商品軟體所用。再此說一下硬碟序列號分為兩中1邏輯序列號,2物理硬碟 序列號。後者是硬碟出廠時所固定唯一程式碼,如在DOS下可以直接透過IN,OUT讀寫埠來獲取,但WIN下就須寫VXD來實現此操作。 思路和實現方法已經給出。再具體的自己來做吧。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993861/,如需轉載,請註明出處,否則將追究法律責任。

相關文章