我是靠谱客的博主 默默鱼,最近开发中收集的这篇文章主要介绍Qt--探讨.exe程序加密一、前言二、分析三、实现(核心代码)四、效果附:MD5加密注册码,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
一、前言
程序员随着代码写的多,难免会接到一些私活。但是又怕对方白嫖,困难总比办法多,哦不,错了,办法总比困难多。为了避免被别人白嫖,我们可以给自己的程序留后手,网上查阅资料,大概有以下两种:
1、采用远程控制:UDP指令远程锁死程序;
2、采用本地加密:提取CPU和硬盘序列号,加密生成注册码;
以上两种方法各有利弊,方法1可以本人自由控制,但是一旦设备没网,就GG了;方法2则不依赖网络,且每台设备的注册码唯一,但是本人无法直接控制。个人认为还是方法2简单有效,所以下面就方法2进行具体分析。
二、分析
采用注册码机制,我们首先要生成注册码,Qt下获取CPU和硬盘等系统信息(针对windows系统)的方法如下:
windows下执行命令除了用cmd
之外,还有个东西叫WMIC
,非常强大,可以通过他获取很多信息,包括硬件信息。
QString Widget::getWMIC(const QString &cmd)
{
//获取cpu名称:wmic cpu get Name
//获取cpu核心数:wmic cpu get NumberOfCores
//获取cpu线程数:wmic cpu get NumberOfLogicalProcessors
//查询cpu序列号:wmic cpu get processorid
//查询主板序列号:wmic baseboard get serialnumber
//查询BIOS序列号:wmic bios get serialnumber
//查看硬盘:wmic diskdrive get serialnumber
QProcess p;
p.start(cmd);
p.waitForFinished();
QString result = QString::fromLocal8Bit(p.readAllStandardOutput());
QStringList list = cmd.split(" ");
result = result.remove(list.last(), Qt::CaseInsensitive);
result = result.replace("r", "");
result = result.replace("n", "");
result = result.simplified();
return result;
}
QString Widget::getCpuName()
{
return getWMIC("wmic cpu get name");
}
QString Widget::getCpuId()
{
return getWMIC("wmic cpu get processorid");
}
QString Widget::getDiskNum()
{
return getWMIC("wmic diskdrive where index=0 get serialnumber");
}
获取注册码之后,就可以着手程序的加密了,我的策略是这样的:
- 如果程序没有注册,默认可以使用3次;
- 如果程序注册了,使用次数无限制;
那怎么限制程序的使用次数呢?我的策略是这样的:
- 生成一个System.ini配置文件,里面存放程序的剩余运行次数
RemainTime:3
; - 但是
RemainTime:3
当然不能直接存在System.ini中,不然一眼看出来就可以自己修改次数了; - 所以在对System.ini写之前,进行加密;对System.ini读之后,进行解密;
- 加/解密算法可以自行选取,但是要采用可逆算法;
- 然后判断剩余运行次数,如果小于等于0,则程序提示需注册后使用,并退出;
- 否则,剩余运行次数减1,程序正常运行;
三、实现(核心代码)
QString Widget::getWMIC(const QString &cmd)
{
//获取cpu名称:wmic cpu get Name
//获取cpu核心数:wmic cpu get NumberOfCores
//获取cpu线程数:wmic cpu get NumberOfLogicalProcessors
//查询cpu序列号:wmic cpu get processorid
//查询主板序列号:wmic baseboard get serialnumber
//查询BIOS序列号:wmic bios get serialnumber
//查看硬盘:wmic diskdrive get serialnumber
QProcess p;
p.start(cmd);
p.waitForFinished();
QString result = QString::fromLocal8Bit(p.readAllStandardOutput());
QStringList list = cmd.split(" ");
result = result.remove(list.last(), Qt::CaseInsensitive);
result = result.replace("r", "");
result = result.replace("n", "");
result = result.simplified();
return result;
}
QString Widget::getCpuId() //获取CPU序列号
{
return getWMIC("wmic cpu get processorid");
}
QString Widget::getDiskNum() //获取硬盘序列号
{
return getWMIC("wmic diskdrive where index=0 get serialnumber");
}
QString Widget::Encode(QString row) //加密,由于加/解密不是本文重点,故简单处理一下
{
QByteArray byteArray = row.toUtf8();
byteArray = byteArray.toBase64();
return byteArray;
}
QString Widget::Decode(QString passwd) //解密
{
QByteArray byteArray = passwd.toUtf8();
byteArray = QByteArray::fromBase64(byteArray);
return byteArray;
}
void Widget::Judge_Valid() //判断程序合法性
{
QString filePath = "System.ini";
QFile file(filePath);
if(!file.exists()) { //如果文件不存在
file.open(QIODevice::ReadWrite | QIODevice::Text); //新建文件
QString info = "RemainTime:"+time; //time是全局变量,QString time = "3";
file.write(Encode(info).toUtf8()); //写入信息
file.close();
goto Here;
}else { //如果文件存在
Here:if(file.open(QFile::ReadWrite | QFile::Text)) { //打开文件
QString info = file.readAll(); //读取信息
if(info.isEmpty()) { //如果文件为空
QString time_temp = "1";
QString info = "RemainTime:"+time_temp;
file.write(Encode(info).toUtf8()); //写入信息
info = file.readAll();
}
info = Decode(info); //解码
if(info.contains(':')) { //信息正确
QStringList list = info.split(':');
if(list.length()>=1) {
if(list[1].toInt() <= 0) { //程序剩余使用次数不足
QMessageBox::about(this,"提示","请注册后再使用!");
exit(0); //程序退出
}else { //程序还有剩余使用次数
file.close();
file.open(QFile::ReadWrite | QFile::Text | QFile::Truncate); //清空文件内容
QString time_remain = QString::number(list[1].toInt()-1); //程序剩余使用次数减1
QString info = "RemainTime:"+time_remain;
file.write(Encode(info).toUtf8()); //更新程序剩余使用次数
QMessageBox::about(this,"提示","程序剩余使用次数:"+time_remain+"次");
}
}
}
}//Here
file.close();
}//如果文件存在
}
四、效果
附:MD5加密注册码
//获取设备信息字符串
const QString get_SerialNumber()
{
QString cpu_id = "";
QProcess p(0);
p.start("wmic CPU get ProcessorID"); //其它信息也类似
p.waitForStarted();
p.waitForFinished();
cpu_id = QString::fromLocal8Bit(p.readAllStandardOutput());
cpu_id = cpu_id.remove("ProcessorId").trimmed();
QString lpRootPathName = "C:\";
LPTSTR lpVolumeNameBuffer=new TCHAR[12];//磁盘卷标
DWORD nVolumeNameSize=12;// 卷标的字符串长度
DWORD VolumeSerialNumber;//硬盘序列号
DWORD MaximumComponentLength;// 最大的文件长度
LPTSTR lpFileSystemNameBuffer=new TCHAR[10];// 存储所在盘符的分区类型的长指针变量
DWORD nFileSystemNameSize=10;// 分区类型的长指针变量所指向的字符串长度
DWORD FileSystemFlags;// 文件系统的一此标志
GetVolumeInformation((LPTSTR)lpRootPathName.utf16(),
lpVolumeNameBuffer, nVolumeNameSize,
&VolumeSerialNumber, &MaximumComponentLength,
&FileSystemFlags,
lpFileSystemNameBuffer, nFileSystemNameSize);
return (cpu_id.mid(0,4) + "D-"+ cpu_id.mid(4,4) + "R-" +
cpu_id.mid(8,4) + "E-" + cpu_id.mid(12,4) + "A-" +
QString::number(VolumeSerialNumber,10).mid(0,4)+"M");
}
//使用MD5对设备信息字符串进行加密
const QString hash_Encryption(const QString temp)
{
QByteArray byte_array;
byte_array.append(temp);
QByteArray hash_byte_array = QCryptographicHash::hash(byte_array,QCryptographicHash::Md5);
return hash_byte_array.toHex().toUpper();
}
//将加密后的字符串序列化为注册码形式
const QString format_HASHString(const QString hashtemp)
{
QString retemp = "";
for(int i = 0; i < 7; i++)
{
retemp += hashtemp.mid(4*i,4) + "-";
}
retemp += hashtemp.mid(28,4);
return retemp;
}
//去除注册码格式,转化为MD5加密后的字符串
const QString remove_Format(const QString formathash)
{
QString temp = "";
for(int i = 0; i < 8; i++)
{
temp += formathash.mid(5*i,4);
}
return temp;
}
最后
以上就是默默鱼为你收集整理的Qt--探讨.exe程序加密一、前言二、分析三、实现(核心代码)四、效果附:MD5加密注册码的全部内容,希望文章能够帮你解决Qt--探讨.exe程序加密一、前言二、分析三、实现(核心代码)四、效果附:MD5加密注册码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复