一、前言
程序员随着代码写的多,难免会接到一些私活。但是又怕对方白嫖,困难总比办法多,哦不,错了,办法总比困难多。为了避免被别人白嫖,我们可以给自己的程序留后手,网上查阅资料,大概有以下两种:
1、采用远程控制:UDP指令远程锁死程序;
2、采用本地加密:提取CPU和硬盘序列号,加密生成注册码;
以上两种方法各有利弊,方法1可以本人自由控制,但是一旦设备没网,就GG了;方法2则不依赖网络,且每台设备的注册码唯一,但是本人无法直接控制。个人认为还是方法2简单有效,所以下面就方法2进行具体分析。
二、分析
采用注册码机制,我们首先要生成注册码,Qt下获取CPU和硬盘等系统信息(针对windows系统)的方法如下:
windows下执行命令除了用cmd
之外,还有个东西叫WMIC
,非常强大,可以通过他获取很多信息,包括硬件信息。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36QString 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,程序正常运行;
三、实现(核心代码)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87QString 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加密注册码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61//获取设备信息字符串 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--探讨内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复