Windows序列號生成器
VMProtect 是新一代軟件盜版保護解決方案。VMProtect 是目前強大的反盜版解決方案之一,許多領先的軟件發行商都在使用它。VMProtect允許保護可執行文件(EXE,SCR),動態鏈接庫(DLL,OCX,BPL)和驅動程序(SYS)。
加密解密技術交流群(766135708)
Windows 密鑰生成器是用于 x86 和 x64 平臺的 DLL 文件、一個 C 語言頭文件和一個 MSVC 兼容的庫文件。因此,庫既可以靜態鏈接也可以動態加載。生成器的所有文件都位于Keygen\DLL文件夾中。生成序列號的測試應用程序也在那里。
生成器 API
生成器僅導出兩個函數:第一個函數生成一個序列號,而第二個函數釋放第一個函數分配的內存。讓我們從第一個開始:
VMProtectErrors __stdcall VMProtectGenerateSerialNumber ( VMProtectProductInfo * pProductInfo, VMProtectSerialNumberInfo * pSerialInfo, char ** pSerialNumber );第一個參數是指向VMProtect ProductInfo結構的指針,其內容已上傳到 VMProtect(請參閱導出產品參數)。該結構包含產品使用的算法和產品的標識符號。
第二個參數是指向VMProtectSerialNumberInfo結構的指針,其內容被移動到生成的序列號中。該結構包含序列號的所有字段和定義應將哪些字段寫入序列號的位掩碼。
struct VMProtectSerialNumberInfo { INT flags; wchar_t * pUserName; wchar_t * pEMail; DWORD dwExpDate; DWORD dwMaxBuildDate; BYTE nRunningTimeLimit; char * pHardwareID; size_t nUserDataLength; BYTE * pUserData; };flags字段包VMProtectSerialNumberFlags中的位標志,該集合在結構之前進行了描述:
- HAS_USER_NAME – 將pUserName變量中的用戶名放入序列號中。
- HAS_EMAIL – 將pEMail變量中的電子郵件放入序列號中。
- HAS_EXP_DATE – 序列號將在dwExpDate變量中指定的日期之后過期。
- HAS_MAX_BUILD_DATE – 序列號僅適用于在dwMaxBuildDate變量中指定的日期之前構建的產品版本 。
- HAS_TIME_LIMIT – 程序在nRunningTimeLimit變量指定的時間到期后停止工作(時間以分鐘為單位指定,不應超過 255)。
- HAS_HARDWARE_ID – 該程序僅適用于具pHardwar變量中指定的 ID 的硬件。
- HAS_USER_DATA – 將nUserDataLength長度的自定義用戶數據放在pUserData的地址到序列號。
第三個參數是指向指針的指針。生成的序列號的地址寫在那里。生成序列號后,應該復制它,地址必須傳遞給生成器的第二個 API 函數,該函數將釋放序列號占用的內存。
void __stdcall VMProtectFreeSerialNumberMemory ( char * pSerialNumber);
VMProtectGenerateSerialNumber函數返回一個VMProtectErrors值,如果成功生成序列號,則該值包含 0,或者包含一個錯誤代碼。可能的錯誤代碼是:
- ALL_RIGHT – 沒有錯誤,序列號已生成。
- UNSUPPORTED_ALGORITHM – 在函數的第一個參數中傳遞了不正確的密鑰加密算法。
- UNSUPPORTED_NUMBER_OF_BITS – 在函數的第一個參數中傳遞了不正確的位數。
- USER_NAME_IS_TOO_LONG – UTF-8 編碼的用戶名長度超過 255 字節。
- EMAIL_IS_TOO_LONG – UTF-8 編碼的用戶電子郵件的長度超過 255 字節。
- USER_DATA_IS_TOO_LONG – 用戶數據的長度超過 255 字節。
- HWID_HAS_BAD_SIZE – 硬件標識符的大小不正確。
- PRODUCT_CODE_HAS_BAD_SIZE – 在函數的第一個參數中傳遞的產品標識符大小不正確。
- SERIAL_NUMBER_TOO_LONG – 序列號太長,無法滿足算法中指定的位數。
- BAD_PRODUCT_INFO – 函數的第一個參數不正確或為 NULL。
- BAD_SERIAL_NUMBER_INFO – 函數的第二個參數不正確或為 NULL。
- BAD_SERIAL_NUMBER_CONTAINER – 該函數的第三個參數未指向要寫入序列號地址的內存。
- NOT_EMPTY_SERIAL_NUMBER_CONTAINER – 函數的第三個參數不指向空內存單元,該單元必須為 NULL。
- BAD_PRIVATE_EXPONENT – 函數的第一個參數包含不正確的私有指數值。
- BAD_MODULUS – 函數的第一個參數包含不正確的模數值。
錯誤可以分為兩類:由不正確的參數或第一個參數的不正確值引起的錯誤,以及其他所有錯誤。第一類錯誤很少見,它們表示結構配置不正確。您應該重新上傳產品信息并檢查結構是否填寫正確。可以在下面找到正確填充結構的示例。
第二類錯誤是由于嘗試向鍵中放入超過其大小所能容納的更多數據而引起的。在這種情況下,我們建議向電子商務提供商發送一條消息,其中包含“密鑰將在 24 小時內發送”之類的文本,而不是實際的序列號,并將所有必需的信息發送到您自己的電子郵箱。在這種情況下,密鑰是在 VMProtect 中手動生成的,一些數據被截斷以適應最大密鑰大小的所有關鍵信息。
使用示例
下面是調用上述函數并生成序列號的代碼示例。注意最開始的代碼塊。在您將其替換為從 VMProtect 為您的產品導出的示例之前,該示例將不起作用:
////////////////////////////////////////////////////////////////////////// // !!! this block should be generated by VMProtect !!! /// ////////////////////////////////////////////////////////////////////////// VMProtectAlgorithms g_Algorithm = ALGORITHM_RSA; size_t g_nBits = 0; byte g_vModulus[1]; byte g_vPrivate[1]; byte g_vProductCode[1]; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { VMProtectProductInfo pi; pi.algorithm = g_Algorithm; pi.nBits = g_nBits; pi.nModulusSize = sizeof(g_vModulus); pi.pModulus = g_vModulus; pi.nPrivateSize = sizeof(g_vPrivate); pi.pPrivate = g_vPrivate; pi.nProductCodeSize = sizeof(g_vProductCode); pi.pProductCode = g_vProductCode; VMProtectSerialNumberInfo si = {0}; si.flags = HAS_USER_NAME | HAS_EMAIL; si.pUserName = L"John Doe"; si.pEMail = L"john@doe.com"; char * pBuf = NULL; VMProtectErrors res = VMProtectGenerateSerialNumber(&pi, &si, &pBuf); if (res == ALL_RIGHT) { printf("Serial number:\n%s\n", pBuf); VMProtectFreeSerialNumberMemory(pBuf); } else { printf("Error: %d\n", res); } return 0;
這是來自Keygen\DLL\Example的 Microsoft Visual Studio 示例項目。下面是代碼中最有趣的部分以及我們的評論。
main函數的第一行使用從 VMProtect 導出的數據填充VMProtectProductInfo結構。此代碼是典型的,不應更改以避免錯誤。然后我們創建VMProtectSerialNumberInfo結構并將用戶名和電子郵件的位組合插入標志字段。在下一行中,我們將用戶名和密碼放入結構中的相應字段。請注意,值在 UNICODE 編碼中被接受。密鑰生成器會將它們轉換為 UTF-8。
然后,我們初始化一個指針變量,用于存儲生成的密鑰的地址,并調用VMProtectGenerateSerialNumber,然后分析返回碼。如果沒有錯誤,生成的密鑰將輸出到控制臺,并調用免費序列號記憶功能。
VMprotect SerialNumberInfo 結構的其余字段
結構的某些字段可能需要一些額外的解釋。例如,dwExpDate和dwMaxBuildDate字段包含特定格式的日期:0xYYYYMMDD,即年存儲在高位字中,月和日分別存儲在低位字的高低字節中。為了產生這樣的數字,使用了以下宏:MAKEDATE(y, m, d)。您可以這樣稱呼它:MAKEDATE(2010, 05, 12)。pHardwareID字段應包含指向許可 SDK的VMProtectGetCurrentHWID方法返回的字符串的指針。