一、原理分析
通過分析VMProtect憑證管理的配置過程、測試各項配置的實際效果,可以推斷憑證管理的基本原理如下:
1、利用RSA算法生成一個公私鑰對;
2、將公鑰寫入到加殼後的可執行文件,用於解密註冊碼;
3、根據用戶的配置,將客戶名稱、E-Mail、硬件碼、截止日期、運行時間限制、最終創建日期、使用者信息、被屏蔽註冊碼中選中的字段用私鑰加密後寫入到加殼後的可執行文件;
4、加殼後的可執行文件運行時,獲取用戶提供的註冊碼,然後用保存在自身內部的公鑰對其進行解密,解密之後對各類限制條件(各類限制條件的含義如下表)進行判斷,如果不符合就拒絕運行。
字段 | 含義 | 說明 |
客戶名稱 | 用戶名 | 提示信息,無限制作用 |
用戶的郵箱地址 | 提示信息,無限制作用 | |
硬件碼 | 根據MAC、CPU、BIOS等信息計算得到的計算機的唯一標示 | 限制軟件只能在指定的機器上運行 |
截止日期 | 軟件可以運行的截止日期 | 限制軟件只能在指定日期之前運行 |
運行時間限制 | 軟件啓動可以運行的時間(單位分鐘) | 限制軟件每次的運行時間 |
最終創建日期 | 允許運行的最晚編譯時間 | 常用於限制更新服務,比如此日期設置爲2016-1-1,那麼對於2016-1-1之後編譯的軟件,註冊碼將無效 |
使用者信息 | 自定義的一些信息 | 用法暫不知 |
被屏蔽註冊碼 | 被屏蔽的註冊碼將無效 | 黑名單,但這個黑名單應該沒有通過網絡進行遠程驗證。因此對於此註冊碼尚未被拉黑的軟件版本是起不到限制作用的 |
二、用法
1、在代碼中使用憑證管理功能
代碼如下,假設編譯得到程序爲test.exe
#include<windows.h>
#include"VMProtectSDK.h"
#pragmacomment(lib, "VMProtectSDK32.lib")
voidprint_state(INT state)
{
if (state& SERIAL_STATE_FLAG_CORRUPTED)
{
MessageBox(NULL,"許可文件損壞", "錯誤", 0);
}
else if(state & SERIAL_STATE_FLAG_INVALID)
{
MessageBox(NULL,"許可文件無效", "錯誤", 0);
}
else if(state & SERIAL_STATE_FLAG_BLACKLISTED)
{
MessageBox(NULL,"許可文件被列入黑名單", "錯誤", 0);
}
else if(state & SERIAL_STATE_FLAG_DATE_EXPIRED)
{
MessageBox(NULL,"許可文件過期", "錯誤", 0);
}
else if(state & SERIAL_STATE_FLAG_RUNNING_TIME_OVER)
{
MessageBox(NULL,"許可文件時限到", "錯誤", 0);
}
else if(state & SERIAL_STATE_FLAG_BAD_HWID)
{
MessageBox(NULL,"硬件ID不符","錯誤", 0);
}
else if(state & SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED)
{
MessageBox(NULL,"版本過期", "錯誤", 0);
}
}
char*read_serial(const char *fname)
{
FILE *f =fopen(fname, "rb");
if (NULL== f) return NULL;
fseek(f,0, SEEK_END);
int s =ftell(f);
fseek(f,0, SEEK_SET);
char *buf= new char[s + 1];
fread(buf,s, 1, f);
buf[s] =0;
fclose(f);
returnbuf;
}
boolValidSerial()
{
char*serial = read_serial("serial.txt");
int res =VMProtectSetSerialNumber(serial);
delete[]serial;
if (res)
{
print_state(res);
returnfalse;
}
returnTRUE;
}
int_tmain(int argc, _TCHAR* argv[])
{
if (argc== 2)
{
int nSize= VMProtectGetCurrentHWID(NULL, 0); // get number of required bytes
char*pBuf = new char[nSize]; // allocate buffer
VMProtectGetCurrentHWID(pBuf,nSize); // obtain hardeare identifier// use it
printf("%s\n",pBuf);
deletepBuf;
}
else
{
if (ValidSerial())
printf("ok\n");
else
printf("err\n");
}
return 0;
}
2、配置憑證管理參數得到註冊碼
點擊 授權管理→生成
根據需求,選擇相應的內容,點擊序列號,然後把序列號保存到serial.txt文件中。如果序列號內容包括硬件碼,運行test.exe aaa(任意加一個參數即可)即可得到本機的硬件碼。
3、運行測試
把serial.txt文件與exe文件放到同一目錄下,運行exe進行測試,看是否達到預期效果。