#include "pch.h"
#include <Windows.h>
#include <Wbemidl.h>
#include <comdef.h>
#include <WinCrypt.h>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "Crypt32.lib")
// 导出函数声明
extern "C" __declspec(dllexport) const char* GetMachineCode();
extern "C" __declspec(dllexport) const char* ComputeRegistration(const char* machineCode, int daysChoice);
extern "C" __declspec(dllexport) BOOL SaveRegistration(const char* machineCode, const char* regCode, int daysChoice);
extern "C" __declspec(dllexport) int ValidateLicense();
// 全局缓冲区用于返回字符串
thread_local static char g_buffer[256] = { 0 };
// 获取机器码函数
const char* GetMachineCode() {
HRESULT hres;
std::string serials;
// 初始化COM
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
strcpy_s(g_buffer, "COM Init Failed");
return g_buffer;
}
// 设置安全级别
hres = CoInitializeSecurity(
NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL
);
if (FAILED(hres)) {
CoUninitialize();
strcpy_s(g_buffer, "Security Init Failed");
return g_buffer;
}
// 创建WMI实例
IWbemLocator* pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pLoc
);
if (FAILED(hres)) {
CoUninitialize();
strcpy_s(g_buffer, "WMI Locator Failed");
return g_buffer;
}
// 连接WMI
IWbemServices* pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), NULL, NULL,
0, NULL, 0, 0, &pSvc
);
if (FAILED(hres)) {
pLoc->Release();
CoUninitialize();
strcpy_s(g_buffer, "WMI Connect Failed");
return g_buffer;
}
// 设置代理安全
hres = CoSetProxyBlanket(
pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE
);
if (FAILED(hres)) {
pSvc->Release();
pLoc->Release();
CoUninitialize();
strcpy_s(g_buffer, "Proxy Setup Failed");
return g_buffer;
}
// 执行查询
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT SerialNumber FROM Win32_DiskDrive"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &pEnumerator
);
if (FAILED(hres)) {
pSvc->Release();
pLoc->Release();
CoUninitialize();
strcpy_s(g_buffer, "Query Failed");
return g_buffer;
}
// 处理查询结果
IWbemClassObject* pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator) {
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (uReturn == 0) break;
VARIANT vtProp;
VariantInit(&vtProp);
// 获取序列号
hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
if (SUCCEEDED(hr) && vtProp.vt == VT_BSTR) {
_bstr_t bstr(vtProp.bstrVal);
serials += (const char*)bstr;
}
VariantClear(&vtProp);
pclsObj->Release();
}
// 清理资源
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
// 计算MD5哈希
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
BYTE rgbHash[16];
DWORD cbHash = 16;
CHAR rgbDigits[] = "0123456789abcdef";
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
strcpy_s(g_buffer, "Crypto Context Failed");
return g_buffer;
}
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
CryptReleaseContext(hProv, 0);
strcpy_s(g_buffer, "Hash Creation Failed");
return g_buffer;
}
if (!CryptHashData(hHash, (BYTE*)serials.c_str(), (DWORD)serials.length(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
strcpy_s(g_buffer, "Hashing Failed");
return g_buffer;
}
if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) {
std::string hashStr;
for (DWORD i = 0; i < cbHash; i++) {
char hex[3];
sprintf_s(hex, "%02x", rgbHash[i]);
hashStr += hex;
}
strcpy_s(g_buffer, hashStr.c_str());
}
else {
strcpy_s(g_buffer, "Hash Retrieval Failed");
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return g_buffer;
}
// 计算注册码
const char* ComputeRegistration(const char* machineCode, int daysChoice) {
int days;
switch (daysChoice) {
case 0: days = 7; break;
case 1: days = 15; break;
case 2: days = 30; break;
default: days = 9999; // 永久
}
std::string mc(machineCode);
if (mc.length() < 5) {
strcpy_s(g_buffer, "Invalid Machine Code");
return g_buffer;
}
// 算法:前4字符 + (第5字符ASCII+天数) + 反转字符前4 + 天数*100
std::string part1 = mc.substr(0, 4);
char c = mc[4];
std::string part2 = std::to_string(static_cast<int>(c) + days);
std::string reversed = mc;
std::reverse(reversed.begin(), reversed.end());
std::string part3 = reversed.substr(0, 4);
std::string part4 = std::to_string(days * 100);
std::string regCode = part1 + part2 + part3 + part4;
strcpy_s(g_buffer, regCode.c_str());
return g_buffer;
}
// 保存注册信息
BOOL SaveRegistration(const char* machineCode, const char* regCode, int daysChoice) {
HKEY hKey;
std::string subkey = "Software\\MyPlugin\\";
subkey += machineCode;
// 创建注册表项
if (RegCreateKeyExA(
HKEY_CURRENT_USER,
subkey.c_str(),
0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) {
return FALSE;
}
// 写入注册码
if (RegSetValueExA(
hKey, "Registration", 0, REG_SZ,
(const BYTE*)regCode, (DWORD)strlen(regCode) + 1) != ERROR_SUCCESS) {
RegCloseKey(hKey);
return FALSE;
}
// 写入天数选项
std::string daysStr = std::to_string(daysChoice);
if (RegSetValueExA(
hKey, "ExpireDays", 0, REG_SZ,
(const BYTE*)daysStr.c_str(), (DWORD)daysStr.length() + 1) != ERROR_SUCCESS) {
RegCloseKey(hKey);
return FALSE;
}
// 写入注册日期 (使用系统时间)
SYSTEMTIME st;
GetLocalTime(&st);
char dateStr[32];
sprintf_s(dateStr, "%04d%02d%02d%02d%02d%02d",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
if (RegSetValueExA(
hKey, "RegisterDate", 0, REG_SZ,
(const BYTE*)dateStr, (DWORD)strlen(dateStr) + 1) != ERROR_SUCCESS) {
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
return TRUE;
}
// 验证授权
int ValidateLicense() {
const char* machineCode = GetMachineCode();
if (!machineCode || strlen(machineCode) == 0) {
return 0; // 获取机器码失败
}
std::string subkey = "Software\\MyPlugin\\";
subkey += machineCode;
HKEY hKey;
if (RegOpenKeyExA(
HKEY_CURRENT_USER,
subkey.c_str(),
0, KEY_READ, &hKey) != ERROR_SUCCESS) {
return -1; // 未注册
}
// 读取注册信息
char regDate[32] = { 0 };
DWORD size = sizeof(regDate);
if (RegQueryValueExA(
hKey, "RegisterDate", NULL, NULL,
(LPBYTE)regDate, &size) != ERROR_SUCCESS) {
RegCloseKey(hKey);
return -1;
}
char daysChoice[10] = { 0 };
size = sizeof(daysChoice);
if (RegQueryValueExA(
hKey, "ExpireDays", NULL, NULL,
(LPBYTE)daysChoice, &size) != ERROR_SUCCESS) {
RegCloseKey(hKey);
return -1;
}
RegCloseKey(hKey);
// 解析注册日期
int year, month, day, hour, min, sec;
if (sscanf_s(regDate, "%4d%2d%2d%2d%2d%2d",
&year, &month, &day, &hour, &min, &sec) != 6) {
return -1;
}
// 计算已过天数
SYSTEMTIME regTime = { 0 };
regTime.wYear = year;
regTime.wMonth = month;
regTime.wDay = day;
FILETIME ftReg, ftNow;
SystemTimeToFileTime(®Time, &ftReg);
GetSystemTimeAsFileTime(&ftNow);
ULARGE_INTEGER ulReg, ulNow;
ulReg.LowPart = ftReg.dwLowDateTime;
ulReg.HighPart = ftReg.dwHighDateTime;
ulNow.LowPart = ftNow.dwLowDateTime;
ulNow.HighPart = ftNow.dwHighDateTime;
ULONGLONG diff = ulNow.QuadPart - ulReg.QuadPart;
int daysPassed = static_cast<int>(diff / (10000000ULL * 60 * 60 * 24));
// 检查授权状态
int choice = atoi(daysChoice);
if (choice == 3) return 1; // 永久授权
int maxDays = 0;
switch (choice) {
case 0: maxDays = 7; break;
case 1: maxDays = 15; break;
case 2: maxDays = 30; break;
default: return 0;
}
return (daysPassed <= maxDays) ? 1 : 0;
}
运行测试
最新发布