VC++ 注册码加密系统源码
·
一、系统架构设计
1.1 加密体系架构
┌─────────────────────────────────────────────┐
│ VC++ 注册码加密系统 │
├─────────────────────────────────────────────┤
│ 1. 机器指纹采集模块 │
│ - CPU ID / 硬盘序列号 / MAC地址 │
│ - 主板BIOS序列号 / 操作系统ID │
├─────────────────────────────────────────────┤
│ 2. 注册码生成模块 │
│ - 基于机器指纹生成唯一标识 │
│ - 时间戳 + 随机数种子 │
│ - 产品版本 + 授权期限 │
├─────────────────────────────────────────────┤
│ 3. 多层加密引擎 │
│ - AES-256 对称加密 │
│ - RSA-2048 非对称签名 │
│ - SHA-256 哈希校验 │
│ - Base64 编码传输 │
├─────────────────────────────────────────────┤
│ 4. 注册验证模块 │
│ - 本地注册表/文件验证 │
│ - 在线服务器验证(可选) │
│ - 硬件绑定验证 │
│ - 有效期检查 │
├─────────────────────────────────────────────┤
│ 5. 反破解保护模块 │
│ - 代码混淆 + 花指令 │
│ - 反调试检测(IsDebuggerPresent) │
│ - 注册表监控 + 文件完整性校验 │
│ - 虚拟机检测 │
└─────────────────────────────────────────────┘
1.2 支持的加密算法
| 算法类型 | 具体实现 | 用途 |
|---|---|---|
| 对称加密 | AES-256, DES, 3DES | 注册码核心数据加密 |
| 非对称加密 | RSA-1024/2048/4096 | 数字签名和密钥交换 |
| 哈希算法 | SHA-256, MD5, CRC32 | 数据完整性校验 |
| 编码算法 | Base64, Hex | 二进制数据编码 |
二、完整源码实现
2.1 主程序框架(RegCodeSystem.cpp)
/**
* @file RegCodeSystem.cpp
* @brief VC++ 注册码加密系统主程序
* @version 3.0
* @date 2024-01-01
*/
#include "stdafx.h"
#include "RegCodeSystem.h"
#include "MachineFingerprint.h"
#include "CryptoEngine.h"
#include "RegValidator.h"
#include "AntiCrack.h"
// 全局对象
CMachineFingerprint g_MachineFP;
CCryptoEngine g_Crypto;
CRegValidator g_Validator;
CAntiCrack g_AntiCrack;
// 注册信息结构
typedef struct _REG_INFO {
char szProductName[64]; // 产品名称
char szProductVersion[16]; // 产品版本
char szRegCode[512]; // 注册码
char szMachineID[128]; // 机器标识
SYSTEMTIME stExpireDate; // 过期日期
DWORD dwRegType; // 注册类型(试用/正式/企业)
DWORD dwUserCount; // 用户数量
BYTE bSignature[256]; // 数字签名
DWORD dwChecksum; // 校验和
} REG_INFO, *PREG_INFO;
// 主函数
int main(int argc, char* argv[])
{
// 1. 反破解保护
if (!g_AntiCrack.Initialize())
{
MessageBoxA(NULL, "系统检测到调试环境!", "错误", MB_ICONERROR);
return -1;
}
// 2. 检查是否已注册
REG_INFO regInfo = {0};
if (g_Validator.LoadRegInfo(®Info))
{
if (g_Validator.VerifyRegCode(®Info))
{
printf("软件已注册,欢迎使用!\n");
ShowRegInfo(®Info);
return 0;
}
else
{
printf("注册信息无效或已过期!\n");
}
}
// 3. 生成机器指纹
char szMachineID[128] = {0};
if (!g_MachineFP.GetMachineID(szMachineID, sizeof(szMachineID)))
{
MessageBoxA(NULL, "获取机器指纹失败!", "错误", MB_ICONERROR);
return -1;
}
// 4. 生成注册码
char szRegCode[512] = {0};
if (!GenerateRegCode(szMachineID, szRegCode, sizeof(szRegCode)))
{
MessageBoxA(NULL, "生成注册码失败!", "错误", MB_ICONERROR);
return -1;
}
// 5. 保存注册信息
strcpy_s(regInfo.szProductName, "MyApplication");
strcpy_s(regInfo.szProductVersion, "1.0.0");
strcpy_s(regInfo.szRegCode, szRegCode);
strcpy_s(regInfo.szMachineID, szMachineID);
regInfo.dwRegType = REG_TYPE_OFFICIAL;
regInfo.dwUserCount = 1;
// 设置过期时间为一年后
GetLocalTime(®Info.stExpireDate);
regInfo.stExpireDate.wYear += 1;
// 6. 加密并保存注册信息
if (!g_Validator.SaveRegInfo(®Info))
{
MessageBoxA(NULL, "保存注册信息失败!", "错误", MB_ICONERROR);
return -1;
}
printf("注册成功!感谢您的购买。\n");
ShowRegInfo(®Info);
return 0;
}
// 生成注册码
BOOL GenerateRegCode(LPCSTR lpszMachineID, LPSTR lpszRegCode, DWORD dwSize)
{
// 1. 准备原始数据
char szRawData[1024] = {0};
sprintf_s(szRawData, sizeof(szRawData),
"PRODUCT:MyApplication|VERSION:1.0.0|MACHINE:%s|USERS:1|EXPIRE:365",
lpszMachineID);
// 2. 生成AES密钥
BYTE aesKey[32] = {0};
BYTE aesIV[16] = {0};
if (!g_Crypto.GenerateAESKey(aesKey, sizeof(aesKey), aesIV, sizeof(aesIV)))
{
return FALSE;
}
// 3. AES加密
BYTE encryptedData[1024] = {0};
DWORD encryptedLen = 0;
if (!g_Crypto.AESEncrypt((BYTE*)szRawData, strlen(szRawData),
encryptedData, &encryptedLen,
aesKey, sizeof(aesKey), aesIV, sizeof(aesIV)))
{
return FALSE;
}
// 4. RSA签名
BYTE signature[256] = {0};
DWORD sigLen = 0;
if (!g_Crypto.RSASign(encryptedData, encryptedLen, signature, &sigLen))
{
return FALSE;
}
// 5. Base64编码
char base64Data[2048] = {0};
DWORD base64Len = 0;
if (!g_Crypto.Base64Encode(encryptedData, encryptedLen, base64Data, &base64Len))
{
return FALSE;
}
// 6. 格式化注册码
sprintf_s(lpszRegCode, dwSize,
"%s|SIG:%s|KEY:%s|IV:%s",
base64Data,
BinaryToHex(signature, sigLen).c_str(),
BinaryToHex(aesKey, sizeof(aesKey)).c_str(),
BinaryToHex(aesIV, sizeof(aesIV)).c_str());
return TRUE;
}
// 显示注册信息
void ShowRegInfo(PREG_INFO pRegInfo)
{
printf("========== 注册信息 ==========\n");
printf("产品名称: %s\n", pRegInfo->szProductName);
printf("产品版本: %s\n", pRegInfo->szProductVersion);
printf("机器标识: %s\n", pRegInfo->szMachineID);
printf("注册类型: %s\n",
pRegInfo->dwRegType == REG_TYPE_TRIAL ? "试用版" :
pRegInfo->dwRegType == REG_TYPE_OFFICIAL ? "正式版" : "企业版");
printf("用户数量: %d\n", pRegInfo->dwUserCount);
printf("过期日期: %04d-%02d-%02d\n",
pRegInfo->stExpireDate.wYear,
pRegInfo->stExpireDate.wMonth,
pRegInfo->stExpireDate.wDay);
printf("==============================\n");
}
2.2 机器指纹采集(MachineFingerprint.cpp)
/**
* @file MachineFingerprint.cpp
* @brief 机器指纹采集模块
*/
#include "stdafx.h"
#include "MachineFingerprint.h"
#include <windows.h>
#include <iphlpapi.h>
#include <tchar.h>
#pragma comment(lib, "iphlpapi.lib")
// 获取CPU ID
BOOL CMachineFingerprint::GetCPUID(LPSTR lpszCPUID, DWORD dwSize)
{
int CPUInfo[4] = {-1};
__cpuid(CPUInfo, 0);
char szCPUID[64] = {0};
sprintf_s(szCPUID, sizeof(szCPUID), "%08X%08X%08X%08X",
CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
strncpy_s(lpszCPUID, dwSize, szCPUID, _TRUNCATE);
return TRUE;
}
// 获取硬盘序列号
BOOL CMachineFingerprint::GetHardDiskSerial(LPSTR lpszSerial, DWORD dwSize)
{
DWORD dwVolSerial = 0;
DWORD dwMaxComponentLen = 0;
DWORD dwFileSystemFlags = 0;
char szFileSystem[256] = {0};
if (!GetVolumeInformationA("C:\\", NULL, 0, &dwVolSerial,
&dwMaxComponentLen, &dwFileSystemFlags,
szFileSystem, sizeof(szFileSystem)))
{
return FALSE;
}
sprintf_s(lpszSerial, dwSize, "%08X", dwVolSerial);
return TRUE;
}
// 获取MAC地址
BOOL CMachineFingerprint::GetMACAddress(LPSTR lpszMAC, DWORD dwSize)
{
PIP_ADAPTER_INFO pAdapterInfo = NULL;
ULONG ulOutBufLen = 0;
// 第一次调用获取缓冲区大小
GetAdaptersInfo(NULL, &ulOutBufLen);
if (ulOutBufLen == 0)
return FALSE;
pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulOutBufLen);
if (pAdapterInfo == NULL)
return FALSE;
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS)
{
free(pAdapterInfo);
return FALSE;
}
// 获取第一个有效的MAC地址
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter)
{
if (pAdapter->AddressLength == 6)
{
sprintf_s(lpszMAC, dwSize, "%02X%02X%02X%02X%02X%02X",
pAdapter->Address[0], pAdapter->Address[1],
pAdapter->Address[2], pAdapter->Address[3],
pAdapter->Address[4], pAdapter->Address[5]);
free(pAdapterInfo);
return TRUE;
}
pAdapter = pAdapter->Next;
}
free(pAdapterInfo);
return FALSE;
}
// 获取主板BIOS序列号
BOOL CMachineFingerprint::GetBIOSSerial(LPSTR lpszSerial, DWORD dwSize)
{
HKEY hKey = NULL;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\BIOS",
0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
return FALSE;
}
DWORD dwType = 0;
DWORD dwDataSize = dwSize;
LONG lRet = RegQueryValueExA(hKey, "SystemSerialNumber", NULL,
&dwType, (LPBYTE)lpszSerial, &dwDataSize);
RegCloseKey(hKey);
return (lRet == ERROR_SUCCESS);
}
// 获取操作系统ID
BOOL CMachineFingerprint::GetOSID(LPSTR lpszOSID, DWORD dwSize)
{
HKEY hKey = NULL;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Cryptography",
0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
return FALSE;
}
DWORD dwType = 0;
DWORD dwDataSize = dwSize;
LONG lRet = RegQueryValueExA(hKey, "MachineGuid", NULL,
&dwType, (LPBYTE)lpszOSID, &dwDataSize);
RegCloseKey(hKey);
return (lRet == ERROR_SUCCESS);
}
// 生成综合机器指纹
BOOL CMachineFingerprint::GetMachineID(LPSTR lpszMachineID, DWORD dwSize)
{
char szCPUID[64] = {0};
char szHDDSerial[64] = {0};
char szMAC[64] = {0};
char szBIOS[64] = {0};
char szOSID[64] = {0};
GetCPUID(szCPUID, sizeof(szCPUID));
GetHardDiskSerial(szHDDSerial, sizeof(szHDDSerial));
GetMACAddress(szMAC, sizeof(szMAC));
GetBIOSSerial(szBIOS, sizeof(szBIOS));
GetOSID(szOSID, sizeof(szOSID));
// 组合所有指纹信息
char szCombined[512] = {0};
sprintf_s(szCombined, sizeof(szCombined),
"%s|%s|%s|%s|%s",
szCPUID, szHDDSerial, szMAC, szBIOS, szOSID);
// 计算SHA256哈希作为最终机器ID
BYTE hash[32] = {0};
DWORD hashLen = sizeof(hash);
if (!g_Crypto.SHA256Hash((BYTE*)szCombined, strlen(szCombined), hash, &hashLen))
{
return FALSE;
}
// 转换为十六进制字符串
char szHex[65] = {0};
for (int i = 0; i < 32; i++)
{
sprintf_s(szHex + i * 2, sizeof(szHex) - i * 2, "%02X", hash[i]);
}
strncpy_s(lpszMachineID, dwSize, szHex, _TRUNCATE);
return TRUE;
}
2.3 加密引擎(CryptoEngine.cpp)
/**
* @file CryptoEngine.cpp
* @brief 加密引擎模块(AES/RSA/SHA/Base64)
*/
#include "stdafx.h"
#include "CryptoEngine.h"
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")
// 初始化加密提供者
BOOL CCryptoEngine::Initialize()
{
if (!CryptAcquireContext(&m_hProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
{
return FALSE;
}
return TRUE;
}
// 生成AES密钥
BOOL CCryptoEngine::GenerateAESKey(BYTE* pKey, DWORD dwKeyLen, BYTE* pIV, DWORD dwIVLen)
{
if (!CryptGenRandom(m_hProv, dwKeyLen, pKey))
return FALSE;
if (!CryptGenRandom(m_hProv, dwIVLen, pIV))
return FALSE;
return TRUE;
}
// AES加密
BOOL CCryptoEngine::AESEncrypt(BYTE* pData, DWORD dwDataLen,
BYTE* pEncrypted, DWORD* pdwEncryptedLen,
BYTE* pKey, DWORD dwKeyLen,
BYTE* pIV, DWORD dwIVLen)
{
HCRYPTKEY hKey = NULL;
DWORD dwMode = CRYPT_MODE_CBC;
// 导入密钥
if (!CryptImportKey(m_hProv, pKey, dwKeyLen, 0, 0, &hKey))
return FALSE;
// 设置IV
if (!CryptSetKeyParam(hKey, KP_IV, pIV, 0))
{
CryptDestroyKey(hKey);
return FALSE;
}
// 设置加密模式
if (!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0))
{
CryptDestroyKey(hKey);
return FALSE;
}
// 复制数据并加密
memcpy(pEncrypted, pData, dwDataLen);
DWORD dwLen = dwDataLen;
if (!CryptEncrypt(hKey, 0, TRUE, 0, pEncrypted, &dwLen, *pdwEncryptedLen))
{
CryptDestroyKey(hKey);
return FALSE;
}
*pdwEncryptedLen = dwLen;
CryptDestroyKey(hKey);
return TRUE;
}
// AES解密
BOOL CCryptoEngine::AESDecrypt(BYTE* pEncrypted, DWORD dwEncryptedLen,
BYTE* pDecrypted, DWORD* pdwDecryptedLen,
BYTE* pKey, DWORD dwKeyLen,
BYTE* pIV, DWORD dwIVLen)
{
HCRYPTKEY hKey = NULL;
DWORD dwMode = CRYPT_MODE_CBC;
// 导入密钥
if (!CryptImportKey(m_hProv, pKey, dwKeyLen, 0, 0, &hKey))
return FALSE;
// 设置IV
if (!CryptSetKeyParam(hKey, KP_IV, pIV, 0))
{
CryptDestroyKey(hKey);
return FALSE;
}
// 设置解密模式
if (!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0))
{
CryptDestroyKey(hKey);
return FALSE;
}
// 复制数据并解密
memcpy(pDecrypted, pEncrypted, dwEncryptedLen);
DWORD dwLen = dwEncryptedLen;
if (!CryptDecrypt(hKey, 0, TRUE, 0, pDecrypted, &dwLen))
{
CryptDestroyKey(hKey);
return FALSE;
}
*pdwDecryptedLen = dwLen;
CryptDestroyKey(hKey);
return TRUE;
}
// RSA签名
BOOL CCryptoEngine::RSASign(BYTE* pData, DWORD dwDataLen,
BYTE* pSignature, DWORD* pdwSigLen)
{
HCRYPTHASH hHash = NULL;
HCRYPTKEY hKey = NULL;
// 创建哈希对象
if (!CryptCreateHash(m_hProv, CALG_SHA_256, 0, 0, &hHash))
return FALSE;
// 计算哈希值
if (!CryptHashData(hHash, pData, dwDataLen, 0))
{
CryptDestroyHash(hHash);
return FALSE;
}
// 导入RSA私钥(这里使用示例私钥,实际应从证书或密钥容器导入)
BYTE privateKeyBlob[] = { /* RSA私钥Blob数据 */ };
if (!CryptImportKey(m_hProv, privateKeyBlob, sizeof(privateKeyBlob), 0, 0, &hKey))
{
CryptDestroyHash(hHash);
return FALSE;
}
// 签名
if (!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pSignature, pdwSigLen))
{
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
return FALSE;
}
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
return TRUE;
}
// RSA验证签名
BOOL CCryptoEngine::RSAVerify(BYTE* pData, DWORD dwDataLen,
BYTE* pSignature, DWORD dwSigLen)
{
HCRYPTHASH hHash = NULL;
HCRYPTKEY hKey = NULL;
// 创建哈希对象
if (!CryptCreateHash(m_hProv, CALG_SHA_256, 0, 0, &hHash))
return FALSE;
// 计算哈希值
if (!CryptHashData(hHash, pData, dwDataLen, 0))
{
CryptDestroyHash(hHash);
return FALSE;
}
// 导入RSA公钥
BYTE publicKeyBlob[] = { /* RSA公钥Blob数据 */ };
if (!CryptImportKey(m_hProv, publicKeyBlob, sizeof(publicKeyBlob), 0, 0, &hKey))
{
CryptDestroyHash(hHash);
return FALSE;
}
// 验证签名
BOOL bResult = CryptVerifySignature(hHash, pSignature, dwSigLen, hKey, NULL, 0);
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
return bResult;
}
// SHA256哈希
BOOL CCryptoEngine::SHA256Hash(BYTE* pData, DWORD dwDataLen,
BYTE* pHash, DWORD* pdwHashLen)
{
HCRYPTHASH hHash = NULL;
if (!CryptCreateHash(m_hProv, CALG_SHA_256, 0, 0, &hHash))
return FALSE;
if (!CryptHashData(hHash, pData, dwDataLen, 0))
{
CryptDestroyHash(hHash);
return FALSE;
}
DWORD dwHashLen = 32;
if (!CryptGetHashParam(hHash, HP_HASHVAL, pHash, &dwHashLen, 0))
{
CryptDestroyHash(hHash);
return FALSE;
}
*pdwHashLen = dwHashLen;
CryptDestroyHash(hHash);
return TRUE;
}
// Base64编码
BOOL CCryptoEngine::Base64Encode(BYTE* pData, DWORD dwDataLen,
LPSTR lpszEncoded, DWORD* pdwEncodedLen)
{
DWORD dwFlags = CRYPT_STRING_BASE64;
if (!CryptBinaryToStringA(pData, dwDataLen, dwFlags,
lpszEncoded, pdwEncodedLen))
{
return FALSE;
}
return TRUE;
}
// Base64解码
BOOL CCryptoEngine::Base64Decode(LPCSTR lpszEncoded,
BYTE* pDecoded, DWORD* pdwDecodedLen)
{
DWORD dwFlags = CRYPT_STRING_BASE64;
if (!CryptStringToBinaryA(lpszEncoded, 0, dwFlags,
pDecoded, pdwDecodedLen, NULL))
{
return FALSE;
}
return TRUE;
}
2.4 注册验证模块(RegValidator.cpp)
/**
* @file RegValidator.cpp
* @brief 注册验证模块
*/
#include "stdafx.h"
#include "RegValidator.h"
#include "CryptoEngine.h"
// 注册表路径
#define REG_PATH _T("Software\\MyCompany\\MyApplication\\Registration")
// 加载注册信息
BOOL CRegValidator::LoadRegInfo(PREG_INFO pRegInfo)
{
HKEY hKey = NULL;
DWORD dwType = 0;
DWORD dwSize = 0;
// 打开注册表键
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_PATH, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
// 尝试从文件加载
return LoadRegInfoFromFile(pRegInfo);
}
// 读取注册信息
ReadRegString(hKey, _T("ProductName"), pRegInfo->szProductName, sizeof(pRegInfo->szProductName));
ReadRegString(hKey, _T("ProductVersion"), pRegInfo->szProductVersion, sizeof(pRegInfo->szProductVersion));
ReadRegString(hKey, _T("RegCode"), pRegInfo->szRegCode, sizeof(pRegInfo->szRegCode));
ReadRegString(hKey, _T("MachineID"), pRegInfo->szMachineID, sizeof(pRegInfo->szMachineID));
ReadRegDWORD(hKey, _T("RegType"), &pRegInfo->dwRegType);
ReadRegDWORD(hKey, _T("UserCount"), &pRegInfo->dwUserCount);
ReadRegBinary(hKey, _T("Signature"), pRegInfo->bSignature, sizeof(pRegInfo->bSignature));
// 读取过期日期
FILETIME ftExpire = {0};
ReadRegBinary(hKey, _T("ExpireDate"), (BYTE*)&ftExpire, sizeof(FILETIME));
FileTimeToSystemTime(&ftExpire, &pRegInfo->stExpireDate);
RegCloseKey(hKey);
return TRUE;
}
// 保存注册信息
BOOL CRegValidator::SaveRegInfo(PREG_INFO pRegInfo)
{
HKEY hKey = NULL;
DWORD dwDisposition = 0;
// 创建注册表键
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, REG_PATH, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
&hKey, &dwDisposition) != ERROR_SUCCESS)
{
// 保存到文件
return SaveRegInfoToFile(pRegInfo);
}
// 写入注册信息
WriteRegString(hKey, _T("ProductName"), pRegInfo->szProductName);
WriteRegString(hKey, _T("ProductVersion"), pRegInfo->szProductVersion);
WriteRegString(hKey, _T("RegCode"), pRegInfo->szRegCode);
WriteRegString(hKey, _T("MachineID"), pRegInfo->szMachineID);
WriteRegDWORD(hKey, _T("RegType"), pRegInfo->dwRegType);
WriteRegDWORD(hKey, _T("UserCount"), pRegInfo->dwUserCount);
WriteRegBinary(hKey, _T("Signature"), pRegInfo->bSignature, sizeof(pRegInfo->bSignature));
// 写入过期日期
FILETIME ftExpire = {0};
SystemTimeToFileTime(&pRegInfo->stExpireDate, &ftExpire);
WriteRegBinary(hKey, _T("ExpireDate"), (BYTE*)&ftExpire, sizeof(FILETIME));
RegCloseKey(hKey);
return TRUE;
}
// 验证注册码
BOOL CRegValidator::VerifyRegCode(PREG_INFO pRegInfo)
{
// 1. 检查是否过期
SYSTEMTIME stCurrent;
GetLocalTime(&stCurrent);
if (CompareSystemTime(&stCurrent, &pRegInfo->stExpireDate) > 0)
{
MessageBoxA(NULL, "注册码已过期!", "提示", MB_ICONINFORMATION);
return FALSE;
}
// 2. 验证机器指纹
char szCurrentMachineID[128] = {0};
if (!g_MachineFP.GetMachineID(szCurrentMachineID, sizeof(szCurrentMachineID)))
{
return FALSE;
}
if (strcmp(szCurrentMachineID, pRegInfo->szMachineID) != 0)
{
MessageBoxA(NULL, "注册码与当前机器不匹配!", "错误", MB_ICONERROR);
return FALSE;
}
// 3. 解密并验证注册码
if (!DecryptAndVerifyRegCode(pRegInfo))
{
return FALSE;
}
// 4. 验证数字签名
if (!VerifyDigitalSignature(pRegInfo))
{
return FALSE;
}
return TRUE;
}
// 解密并验证注册码
BOOL CRegValidator::DecryptAndVerifyRegCode(PREG_INFO pRegInfo)
{
// 1. 解析注册码格式
char szBase64Data[2048] = {0};
char szSignature[512] = {0};
char szKey[512] = {0};
char szIV[256] = {0};
ParseRegCode(pRegInfo->szRegCode, szBase64Data, sizeof(szBase64Data),
szSignature, sizeof(szSignature),
szKey, sizeof(szKey),
szIV, sizeof(szIV));
// 2. Base64解码
BYTE encryptedData[2048] = {0};
DWORD encryptedLen = 0;
if (!g_Crypto.Base64Decode(szBase64Data, encryptedData, &encryptedLen))
{
return FALSE;
}
// 3. 解密数据
BYTE decryptedData[2048] = {0};
DWORD decryptedLen = 0;
BYTE aesKey[32] = {0};
BYTE aesIV[16] = {0};
HexToBinary(szKey, aesKey, sizeof(aesKey));
HexToBinary(szIV, aesIV, sizeof(aesIV));
if (!g_Crypto.AESDecrypt(encryptedData, encryptedLen,
decryptedData, &decryptedLen,
aesKey, sizeof(aesKey), aesIV, sizeof(aesIV)))
{
return FALSE;
}
// 4. 验证解密后的数据
char szDecrypted[2048] = {0};
memcpy(szDecrypted, decryptedData, decryptedLen);
// 检查产品名称和版本
if (strstr(szDecrypted, pRegInfo->szProductName) == NULL ||
strstr(szDecrypted, pRegInfo->szProductVersion) == NULL)
{
return FALSE;
}
// 检查机器ID
if (strstr(szDecrypted, pRegInfo->szMachineID) == NULL)
{
return FALSE;
}
return TRUE;
}
// 验证数字签名
BOOL CRegValidator::VerifyDigitalSignature(PREG_INFO pRegInfo)
{
BYTE signature[256] = {0};
DWORD sigLen = 0;
HexToBinary((LPCSTR)pRegInfo->bSignature, signature, sizeof(signature));
// 获取注册码原始数据
char szRawData[1024] = {0};
sprintf_s(szRawData, sizeof(szRawData),
"PRODUCT:%s|VERSION:%s|MACHINE:%s|USERS:%d|EXPIRE:%04d-%02d-%02d",
pRegInfo->szProductName,
pRegInfo->szProductVersion,
pRegInfo->szMachineID,
pRegInfo->dwUserCount,
pRegInfo->stExpireDate.wYear,
pRegInfo->stExpireDate.wMonth,
pRegInfo->stExpireDate.wDay);
// 验证签名
return g_Crypto.RSAVerify((BYTE*)szRawData, strlen(szRawData),
signature, sigLen);
}
2.5 反破解保护(AntiCrack.cpp)
/**
* @file AntiCrack.cpp
* @brief 反破解保护模块
*/
#include "stdafx.h"
#include "AntiCrack.h"
#include <windows.h>
#include <tlhelp32.h>
// 检测调试器
BOOL CAntiCrack::DetectDebugger()
{
// 方法1:IsDebuggerPresent
if (IsDebuggerPresent())
return TRUE;
// 方法2:CheckRemoteDebuggerPresent
BOOL bDebuggerPresent = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &bDebuggerPresent);
if (bDebuggerPresent)
return TRUE;
// 方法3:检测调试器窗口
HWND hWnd = FindWindowA("OllyDbg", NULL);
if (hWnd != NULL) return TRUE;
hWnd = FindWindowA("IDA", NULL);
if (hWnd != NULL) return TRUE;
// 方法4:检测调试器进程
if (FindProcess("ollydbg.exe")) return TRUE;
if (FindProcess("idaq.exe")) return TRUE;
if (FindProcess("x64dbg.exe")) return TRUE;
return FALSE;
}
// 检测虚拟机
BOOL CAntiCrack::DetectVirtualMachine()
{
// 方法1:检测VMware
HKEY hKey = NULL;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",
0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
char szValue[256] = {0};
DWORD dwType = 0;
DWORD dwSize = sizeof(szValue);
RegQueryValueExA(hKey, "0", NULL, &dwType, (LPBYTE)szValue, &dwSize);
RegCloseKey(hKey);
if (strstr(szValue, "VMware") != NULL ||
strstr(szValue, "Virtual") != NULL ||
strstr(szValue, "VBOX") != NULL)
{
return TRUE;
}
}
// 方法2:检测虚拟机特征文件
if (GetFileAttributesA("C:\\windows\\system32\\drivers\\vmmouse.sys") != INVALID_FILE_ATTRIBUTES)
return TRUE;
if (GetFileAttributesA("C:\\windows\\system32\\drivers\\vmhgfs.sys") != INVALID_FILE_ATTRIBUTES)
return TRUE;
return FALSE;
}
// 检测进程调试
BOOL CAntiCrack::FindProcess(LPCSTR lpszProcessName)
{
PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return FALSE;
if (Process32First(hSnapshot, &pe32))
{
do
{
if (_stricmp(pe32.szExeFile, lpszProcessName) == 0)
{
CloseHandle(hSnapshot);
return TRUE;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return FALSE;
}
// 代码混淆:插入垃圾指令
void CAntiCrack::InsertJunkCode()
{
__asm {
nop
nop
nop
mov eax, eax
mov ebx, ebx
xor ecx, ecx
add edx, 0
sub esi, 0
push eax
pop eax
}
}
// 反汇编检测
BOOL CAntiCrack::CheckCodeIntegrity()
{
// 获取当前函数的代码
BYTE code[256] = {0};
memcpy(code, (void*)CheckCodeIntegrity, sizeof(code));
// 计算校验和
DWORD checksum = 0;
for (int i = 0; i < sizeof(code); i++)
{
checksum += code[i];
}
// 与预期值比较(实际应存储在加密的地方)
DWORD expectedChecksum = 0x12345678; // 示例值
return (checksum == expectedChecksum);
}
// 初始化反破解保护
BOOL CAntiCrack::Initialize()
{
if (DetectDebugger())
{
MessageBoxA(NULL, "检测到调试器!程序将退出。", "警告", MB_ICONWARNING);
ExitProcess(0);
return FALSE;
}
if (DetectVirtualMachine())
{
MessageBoxA(NULL, "检测到虚拟机环境!某些功能可能受限。", "警告", MB_ICONWARNING);
}
InsertJunkCode();
return TRUE;
}
2.6 注册码生成器(GUI版)
/**
* @file RegGeneratorDlg.cpp
* @brief 注册码生成器对话框
*/
#include "stdafx.h"
#include "RegGeneratorDlg.h"
// 生成注册码按钮
void CRegGeneratorDlg::OnBnClickedBtnGenerate()
{
UpdateData(TRUE);
// 获取机器ID
char szMachineID[128] = {0};
if (!g_MachineFP.GetMachineID(szMachineID, sizeof(szMachineID)))
{
AfxMessageBox(_T("获取机器ID失败!"));
return;
}
// 生成注册码
char szRegCode[512] = {0};
if (!GenerateRegCode(szMachineID, szRegCode, sizeof(szRegCode)))
{
AfxMessageBox(_T("生成注册码失败!"));
return;
}
m_strRegCode = szRegCode;
UpdateData(FALSE);
}
// 保存注册文件
void CRegGeneratorDlg::OnBnClickedBtnSave()
{
UpdateData(TRUE);
if (m_strRegCode.IsEmpty())
{
AfxMessageBox(_T("请先生成注册码!"));
return;
}
CFileDialog dlg(FALSE, _T(".lic"), _T("license.lic"),
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("License Files (*.lic)|*.lic|All Files (*.*)|*.*||"));
if (dlg.DoModal() == IDOK)
{
CFile file;
if (file.Open(dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite))
{
// 加密保存注册码
char szEncrypted[1024] = {0};
EncryptRegFile(m_strRegCode.GetBuffer(), szEncrypted, sizeof(szEncrypted));
file.Write(szEncrypted, strlen(szEncrypted));
file.Close();
AfxMessageBox(_T("注册文件保存成功!"));
}
}
}
三、工程配置
3.1 Visual Studio 工程设置
项目属性:
- 配置属性 → 常规 → 字符集:使用多字节字符集
- C/C++ → 常规 → 附加包含目录:.\include
- C/C++ → 代码生成 → 运行时库:多线程 (/MT)
- 链接器 → 输入 → 附加依赖项:crypt32.lib; iphlpapi.lib
- 链接器 → 高级 → 入口点:WinMainCRTStartup
3.2 编译选项
<!-- 项目配置文件 -->
<PropertyGroup>
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>Static</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>WIN32;_WINDOWS;_SECURE_ATL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
参考代码 VC++编写的注册码加密源程序 www.youwenfan.com/contentcsu/56413.html
四、使用方法
4.1 注册码生成
# 命令行生成注册码
RegCodeSystem.exe /generate /machineid:ABC123 /output license.lic
# 验证注册码
RegCodeSystem.exe /verify /file license.lic
4.2 注册文件格式
-----BEGIN LICENSE-----
PRODUCT:MyApplication|VERSION:1.0.0|MACHINE:ABCDEFG1234567890|USERS:1|EXPIRE:2025-12-31
SIGNATURE:RSA_SIGNATURE_DATA_HERE
ENCRYPTED_DATA:AES_ENCRYPTED_DATA_HERE
-----END LICENSE-----
4.3 集成到应用程序
// 在应用程序启动时调用
BOOL CMyApp::InitInstance()
{
// 检查注册状态
CRegValidator validator;
REG_INFO regInfo = {0};
if (validator.LoadRegInfo(®Info))
{
if (validator.VerifyRegCode(®Info))
{
// 已注册,正常运行
return TRUE;
}
else
{
// 未注册或注册无效
CRegDlg dlg;
if (dlg.DoModal() == IDOK)
{
// 重新验证
if (validator.VerifyRegCode(®Info))
return TRUE;
}
return FALSE;
}
}
else
{
// 未注册,显示注册对话框
CRegDlg dlg;
if (dlg.DoModal() == IDOK)
{
// 保存注册信息
validator.SaveRegInfo(®Info);
return TRUE;
}
return FALSE;
}
}
五、安全建议
5.1 增强安全性
- 代码混淆:使用VMProtect或Themida加壳
- 白盒加密:使用白盒AES实现
- 服务器验证:增加在线激活服务器
- 硬件绑定:绑定TPM芯片或USB Key
- 心跳检测:定期验证注册状态
5.2 防止破解
- 反调试:多重调试器检测
- 反虚拟机:检测虚拟环境
- 完整性校验:检测代码是否被修改
- 分散验证:不在单一函数中进行验证
- 延迟验证:启动后一段时间再进行验证
更多推荐

所有评论(0)