最近遇到一个程序有一个很有趣的认证方式--重启验证,这里根据本人对重启验证的猜想进行实现一下看看
重启验证简介
重启验证:在程序启动的时候验证注册信息,重启验证有一个特点就是会保存注册信息,在启动的时候验证这个注册信息
这个注册信息可以以多种形式保存:比如注册表和文件
执行流程如下图所示:
代码实现
实验环境:Win10 + VS2022 + Qt6
验证注册信息
首先是验证注册信息,这里的验证逻辑是通过用户名计算出一个序列号,然后通过比对用户输入的用户名对应的序列号是否相同,来进行验证
这里以实现功能流程为主,为了图省事,注册信息直接保存在当前目录下了
void VaC_reboot::Verify()
{
// 打开文件
HANDLE hFile = CreateFileW(L"Serial.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 读取文件
char buf[0x100] = { 0 };
DWORD readSize = 0;
ReadFile(hFile, buf, 0x100, &readSize, NULL);
if (readSize == 0) {
CloseHandle(hFile);
return;
}
CloseHandle(hFile);
std::string sbuf = buf;
std::string Uname = sbuf.substr(0, sbuf.find(':'));
std::string USerial = sbuf.substr(sbuf.find(':')+1, sbuf.length());
std::string RealSerial = CalcSerial(Uname);
// 如果文件读取到内容了,比对序列号是否正确,否则进入重启环节
if (readSize) {
if (!strcmp(USerial.c_str(), RealSerial.c_str())) {
QMessageBox::about(this, "Error", "Verify Success!");
ExitProcess(0);
}
else {
QMessageBox::about(this, "Error", "Verify Failed!");
}
}
}
序列号生成
这里就简单随便写一个计算序列号的算法(verifyKey初始为0):
std::string VaC_reboot::CalcSerial(std::string Uname)
{
std::string UserName = Uname;
std::string Serial;
for(auto a:UserName)
{
verifyKey += a;
}
Serial = "VaC_";
Serial += UserName[0] ^ verifyKey;
for (int i = 1; UserName[i]; i++) {
Serial += (UserName[i - 1] ^ UserName[i])%10 + '0';
}
return Serial;
}
保存验证信息
创建文件写入输入的用户名和序列号:
HANDLE hFile = CreateFileW(L"Serial.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
char writeBuf[0x100] = { 0 };
strcpy(writeBuf, ui.lineEdit_UserName->text().toStdString().c_str());
strcat(writeBuf, ":");
strcat(writeBuf, ui.lineEdit_Serial->text().toStdString().c_str());
DWORD dwRet;
WriteFile(hFile, writeBuf, strlen(writeBuf), &dwRet, NULL);
CloseHandle(hFile);
重启程序
所谓重启,无非就是关闭和打开两个基本操作的组合:
// 重启环节
// 获取进程路径
char filePath[MAX_PATH] = { 0 };
GetModuleFileNameA(NULL, filePath, MAX_PATH);
// 创建进程
PROCESS_INFORMATION pi = { 0 };
STARTUPINFOA si = { 0 };
si.cb = sizeof(STARTUPINFOA);
BOOL bRet = CreateProcessA(filePath,
NULL, NULL, NULL, FALSE,
NULL, NULL, NULL, &si, &pi);
// 退出当前进程
ExitProcess(1);
效果展示
打开程序,输入用户名和序列号之后,将输入的信息保存到当前目录下,弹窗提示重启,点击确定后程序重启
因为输入的序列号是胡乱输入的,所以这里一定是认证失败的,之后会再次弹出认证输入窗口
当输入正确的用户名序列号组合之后:(selph:VaC_o2984
)提示认证成功,并退出认证窗口
示例程序
- 示例程序下载:https://github.com/kn0sky/RebootVerify_Demo/releases/download/demo/VaC_reboot.exe
- 源代码github:kn0sky/RebootVerify_Demo (github.com)
参考资料
(6条消息) 重启验证的三种形式及其解决方法_星辞归野的博客-CSDN博客_重启验证