代码
实战代码,实战场景是:
1.废除某软件的注册按钮里面的代码
2.把原来注册按钮的代码执行逻辑,通过VEH HOOK更改为自己dll的某些代码
3.实现了废除原本程序的注册逻辑,更改为自己的注册逻辑算法
4.注入DLL采用的导入表注入
这个是修改的注册机的机器码生成规则,然后点击按钮会把注册码写入注册表
涉及知识点
1.写入注册表信息
2.枚举窗口控件,获取目标窗口控件(编辑框)内容
3.VEH HOOK
4.获取CPU序列号
5.获取第一个网卡的MAC地址
6.生成机器码
7.使用MinHook库挂钩SetWindowTextA
8.导出重要函数
注册机
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <wincrypt.h>
#include <string>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
// 固定 AES-128 密钥(示例)
static const BYTE AES_KEY[16] = {
0x32,0x71,0x19,0x88,0xA6,0x55,0xC3,0xD2,
0x09,0xF1,0xBC,0x44,0xE7,0x6A,0x90,0x1F
};
// 正确导入 AES Key
bool ImportAESKey(HCRYPTPROV hProv, HCRYPTKEY& hKey)
{
struct {
BLOBHEADER hdr;
DWORD keyLen;
BYTE key[16];
} blob = {
{ PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_AES_128 },
16,
{ 0 }
};
memcpy(blob.key, AES_KEY, 16);
return CryptImportKey(
hProv,
(BYTE*)&blob,
sizeof(blob),
0,
0,
&hKey
);
}
// 生成注册码
std::string GenerateLicense(const std::string& plain)
{
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
CryptAcquireContextA(&hProv, NULL, NULL,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
ImportAESKey(hProv, hKey);
BYTE buf[64] = {};
DWORD len = (DWORD)plain.size();
memcpy(buf, plain.data(), len);
// AES 加密(自动 padding)
CryptEncrypt(hKey, 0, TRUE, 0, buf, &len, sizeof(buf));
// 二进制 → 4 位数字分组(不丢信息)
char out[128] = {};
int pos = 0;
for (DWORD i = 0; i < len; i += 2)
{
WORD v = (buf[i] << 8) | buf[i + 1];
pos += sprintf(out + pos, "%04u", v);
if (i + 2 < len) out[pos++] = '-';
}
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return out;
}
int main()
{
char machineCode[32];
char expiry[16];
printf("输入机器码: ");
scanf("%31s", machineCode);
printf("输入到期日 (YYYYMMDD): ");
scanf("%15s", expiry);
std::string plain = std::string(machineCode) + "|" + expiry;
std::string license = GenerateLicense(plain);
printf("\n生成的注册码:\n%s\n", license.c_str());
return 0;
}
注册码解密器
这个只是用来临时测试的,具体的代码都封装在那个DLL中了
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <wincrypt.h>
#include <string>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
static const BYTE AES_KEY[16] = {
0x32,0x71,0x19,0x88,0xA6,0x55,0xC3,0xD2,
0x09,0xF1,0xBC,0x44,0xE7,0x6A,0x90,0x1F
};
bool ImportAESKey(HCRYPTPROV hProv, HCRYPTKEY& hKey)
{
struct {
BLOBHEADER hdr;
DWORD keyLen;
BYTE key[16];
} blob = {
{ PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_AES_128 },
16,
{ 0 }
};
memcpy(blob.key, AES_KEY, 16);
return CryptImportKey(
hProv,
(BYTE*)&blob,
sizeof(blob),
0,
0,
&hKey
);
}
// 解密注册码
std::string DecodeLicense(const char* license)
{
BYTE buf[64] = {};
int idx = 0;
char tmp[128];
strcpy(tmp, license);
// 数字分组 → 二进制
for (char* p = strtok(tmp, "-"); p; p = strtok(NULL, "-"))
{
WORD v = (WORD)atoi(p);
buf[idx++] = (BYTE)(v >> 8);
buf[idx++] = (BYTE)(v & 0xFF);
}
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
CryptAcquireContextA(&hProv, NULL, NULL,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
ImportAESKey(hProv, hKey);
DWORD len = idx;
CryptDecrypt(hKey, 0, TRUE, 0, buf, &len);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return std::string((char*)buf, len);
}
int main()
{
char license[128];
printf("输入注册码: ");
scanf("%127s", license);
std::string plain = DecodeLicense(license);
size_t pos = plain.find('|');
if (pos == std::string::npos)
{
printf("注册码无效\n");
return 0;
}
std::string machineCode = plain.substr(0, pos);
std::string expiry = plain.substr(pos + 1);
printf("\n解密成功\n");
printf("机器码: %s\n", machineCode.c_str());
printf("到期日: %s-%s-%s\n",
expiry.substr(0, 4).c_str(),
expiry.substr(4, 2).c_str(),
expiry.substr(6, 2).c_str());
return 0;
}
判断程序是否到期
这个是判断注册机写入注册表的注册码是否符合标准与到期
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <string>
#include <wincrypt.h>
#pragma comment(lib, "advapi32.lib")
static const BYTE AES_KEY[16] = {
0x32,0x71,0x19,0x88,0xA6,0x55,0xC3,0xD2,
0x09,0xF1,0xBC,0x44,0xE7,0x6A,0x90,0x1F
};
bool ImportAESKey(HCRYPTPROV hProv, HCRYPTKEY& hKey)
{
struct {
BLOBHEADER hdr;
DWORD keyLen;
BYTE key[16];
} blob = {
{ PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_AES_128 },
16,
{ 0 }
};
memcpy(blob.key, AES_KEY, 16);
return CryptImportKey(
hProv,
(BYTE*)&blob,
sizeof(blob),
0,
0,
&hKey
);
}
// 解密注册码
std::string DecodeLicense(const char* license)
{
BYTE buf[64] = {};
int idx = 0;
char tmp[128];
strcpy(tmp, license);
// 数字分组 → 二进制
for (char* p = strtok(tmp, "-"); p; p = strtok(NULL, "-"))
{
WORD v = (WORD)atoi(p);
buf[idx++] = (BYTE)(v >> 8);
buf[idx++] = (BYTE)(v & 0xFF);
}
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
CryptAcquireContextA(&hProv, NULL, NULL,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
ImportAESKey(hProv, hKey);
DWORD len = idx;
CryptDecrypt(hKey, 0, TRUE, 0, buf, &len);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return std::string((char*)buf, len);
}
bool ReadLicenseFromRegistry(char* outBuf, DWORD bufSize)
{
HKEY hKey;
const char* subKey = "Software\\YourCompany\\YourProduct";
if (RegOpenKeyExA(
HKEY_CURRENT_USER,
subKey,
0,
KEY_READ,
&hKey) != ERROR_SUCCESS)
{
return false;
}
DWORD type = REG_SZ;
DWORD size = bufSize;
LONG ret = RegQueryValueExA(
hKey,
"License",
NULL,
&type,
(BYTE*)outBuf,
&size
);
RegCloseKey(hKey);
return ret == ERROR_SUCCESS;
}
//int Mymain()
//{
//
//
// char license[128];
//
//
// if (!ReadLicenseFromRegistry(license, sizeof(license)))
// {
// MessageBoxA(0, "注册码无效!", "提示", MB_OK);
// return 0;
// }
//
// MessageBoxA(0, license, "注册码", MB_OK);
// std::string plain = DecodeLicense(license);
//
// size_t pos = plain.find('|');
// if (pos == std::string::npos)
// {
// MessageBoxA(0, "注册码无效!", "提示", MB_OK);
// return 0;
// }
//
// std::string machineCode = plain.substr(0, pos);
// std::string expiry = plain.substr(pos + 1);
//
// printf("\n解密成功\n");
// printf("机器码: %s\n", machineCode.c_str());
// printf("到期日: %s-%s-%s\n",
// expiry.substr(0, 4).c_str(),
// expiry.substr(4, 2).c_str(),
// expiry.substr(6, 2).c_str());
//
// return 0;
//}
int Mymain()
{
char license[128];
if (!ReadLicenseFromRegistry(license, sizeof(license)))
{
MessageBoxA(NULL, "注册码无效!", "提示", MB_OK | MB_ICONERROR);
ExitProcess(0);
return 0;
}
std::string plain = DecodeLicense(license);
size_t pos = plain.find('|');
if (pos == std::string::npos)
{
MessageBoxA(NULL, "注册码无效!", "提示", MB_OK | MB_ICONERROR);
ExitProcess(0);
return 0;
}
std::string machineCode = plain.substr(0, pos);
std::string expiry = plain.substr(pos + 1); // YYYYMMDD
// 解析到期日
int expYear = atoi(expiry.substr(0, 4).c_str());
int expMonth = atoi(expiry.substr(4, 2).c_str());
int expDay = atoi(expiry.substr(6, 2).c_str());
// 获取本地日期
SYSTEMTIME st;
GetLocalTime(&st);
int today = st.wYear * 10000 + st.wMonth * 100 + st.wDay;
int expireDay = expYear * 10000 + expMonth * 100 + expDay;
char msg[256];
if (today > expireDay)
{
sprintf(msg,
"授权已过期!\n\n到期时间:%04d-%02d-%02d",
expYear, expMonth, expDay);
MessageBoxA(NULL, msg, "授权过期", MB_OK | MB_ICONERROR);
ExitProcess(0);
return 0;
}
else
{
sprintf(msg,
"授权有效 \n\n到期时间:%04d-%02d-%02d",
expYear, expMonth, expDay);
MessageBoxA(NULL, msg, "授权信息", MB_OK | MB_ICONINFORMATION);
}
return 1;
}
// 导出函数供外部调用
extern "C" __declspec(dllexport) void EnableHook()
{
MessageBoxA(NULL, "11", "22", MB_OK);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Mymain();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}



没有回复内容