引言
获取设备信息
功能:将该代码生成的exe发送给使用的用户(也可以是做成带有界面的小程序,目前只是功能阶段)
用户运行后,在当前文件夹下,生成sysInfo_licence.lic文件
用户需要发送这个sysInfo_licence.lic给我们
代码实现:
(1)主函数
//设为1,执行读取硬件的程序,目的;生成exe,发送给用户,用户运行后,在当前文件夹下,生成sysInfo_licence.lic文件。用户需要发送给我们
#ifdef 1
/*
功能说明:执行读取硬件的程序,目的,生成exe,发送给用户,
用户运行后,在当前文件夹下,生成sysInfo_licence.lic文件。
用户需要发送给我们
*/
#define _CRT_SECURE_NO_WARNINGS
#include "GetSYSInfo.h"
//#include "CreateKeyLicence.h"
//#include "Run.h"
//#include "AddDll.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <ctime>
#include <cstdio>
using namespace std;
void main()
{
int GetHardwareInfo_flag = GetSystemHardwareInfo();//读取硬件信息并写进licence中
switch (GetHardwareInfo_flag) {
case 0:
cout << "系统信息获取成功!"<< endl;
break;
case 1:
cout << "Mac获取失败..." << endl; break;
case 2:
cout << "cpu获取失败..." << endl; break;
case 3:
cout << "mac长度获取失败... " << endl; break;
case 4:
cout << "CPU长度获取失败... " << endl; break;
case 5:
cout << "time长度获取失败... " << endl; break;
case 6:
cout << "文件创建失败... " << endl; break;
default:
break;
}
}
#endif
(2)#include "GetSYSInfo.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <ctime>
#include <cstdio>
#include "CpuID.h"
using namespace std;
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
//--------------------------------------------------------------
// 网卡MAC地址
//--------------------------------------------------------------
BOOL GetMacByCmd(char *lpszMac, int len/*=128*/)
{
const long MAX_COMMAND_SIZE = 10000; //命令行输出缓冲大小
TCHAR szFetCmd[] = "ipconfig /all"; //获取MAC命令行
const string strEnSearch = "Physical Address. . . . . . . . . : "; //网卡MAC地址的前导信息
const string strChSearch = "物理地址. . . . . . . . . . . . . : ";
BOOL bret = FALSE;
HANDLE hReadPipe = NULL; //读取管道
HANDLE hWritePipe = NULL; //写入管道
PROCESS_INFORMATION pi; //进程信息
STARTUPINFO si; //控制命令行窗口信息
SECURITY_ATTRIBUTES sa; //安全属性
char szBuffer[MAX_COMMAND_SIZE + 1] = { 0 }; //放置命令行结果的输出缓冲区
string strBuffer;
unsigned long count = 0;
long ipos = 0;
pi.hProcess = NULL;
pi.hThread = NULL;
si.cb = sizeof(STARTUPINFO);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
//1.0 创建管道
bret = CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
if (!bret)
{
goto END;
}
//2.0 设置命令行窗口的信息为指定的读写管道
GetStartupInfo(&si);
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
si.wShowWindow = SW_HIDE; //隐藏命令行窗口
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//3.0 创建获取命令行的进程
bret = CreateProcess(NULL, szFetCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (!bret)
{
goto END;
}
//4.0 读取返回的数据
WaitForSingleObject(pi.hProcess, 2000/*INFINITE*/);
bret = ReadFile(hReadPipe, szBuffer, MAX_COMMAND_SIZE, &count, 0);
if (!bret)
{
goto END;
}
//5.0 查找MAC地址,默认查找第一个,一般为以太网的MAC
strBuffer = szBuffer;
ipos = strBuffer.find(strEnSearch);
if (ipos < 0)//区分中英文的系统
{
ipos = strBuffer.find(strChSearch);
if (ipos < 1)
{
goto END;
}
//提取MAC地址串
strBuffer = strBuffer.substr(ipos + strChSearch.length());
}
else
{
//提取MAC地址串
strBuffer = strBuffer.substr(ipos + strEnSearch.length());
}
ipos = strBuffer.find("\n");
strBuffer = strBuffer.substr(0, ipos);
memset(szBuffer, 0x00, sizeof(szBuffer));
strcpy_s(szBuffer, strBuffer.c_str());
//去掉中间的“00-50-EB-0F-27-82”中间的'-'得到0050EB0F2782
int j = 0;
for (int i = 0; i<strlen(szBuffer); i++)
{
if (szBuffer[i] != '-'&&szBuffer[i] != ' ' && szBuffer[i] != '\n' && szBuffer[i] != '\r')
{
lpszMac[j] = szBuffer[i];
j++;
}
}
bret = TRUE;
END:
//关闭所有的句柄
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return(bret);
}
static string getCurrentTimeStr()
{
time_t t = time(NULL);
char ch[64] = { 0 };
strftime(ch, sizeof(ch) - 1, "%Y$%m$%d", localtime(&t)); //年-月-日 时-分-秒
return ch;
}
int GetSystemHardwareInfo( )
{
char lpszMac[128] = "";
if (!GetMacByCmd(lpszMac, 128))
{
return 1;//Mac获取失败,返回1
}
string macs = lpszMac;
char lpszCpu[128] = "";
if (!GetCpuByCmd(lpszCpu, 128))
{
return 2;//cpu获取失败,返回1
}
string CpuId = lpszCpu;
string TimeStr = getCurrentTimeStr();//获取系统当前时间的字符串:年$月$日格式
int MacIDSize = macs.size();
if (MacIDSize == 0)
{
return 3;//mac长度有误失败,返回3
}
int CPUIDSize = CpuId.size();
if (CPUIDSize == 0)
{
return 4;//CPU长度有误失败,返回4
}
int timeSize = TimeStr.size();
if (timeSize == 0)
{
return 5;//time长度有误失败,返回5
}
ofstream OutFile("sysInfo_licence.lic");
if (OutFile)
{
OutFile << "SystemHardwareInfo:" << "\n" << MacIDSize << "\n" << CPUIDSize << "\n" << timeSize << "\n" << macs << "\n" << CpuId << "\n" << TimeStr;
OutFile.close(); //关闭文件
return 0;//成功,返回0
}
else
{
return 6;//文件创建失败,或者打不开(创建时,默认是会判断是否存在,如果不存在,自动创建的)
}
}
(3)#include "CpuID.h"
#if !defined(AFX_14BEC153_17B9_47BE_845F_71A27BF26B59__INCLUDED_)
#define AFX_14BEC153_17B9_47BE_845F_71A27BF26B59__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <iostream>
#include <string>
#include <windows.h>
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
using namespace std;
//--------------------------------------------------------------
// CPU序列号
//--------------------------------------------------------------
BOOL GetCpuByCmd(char *lpszCpu, int len = 128);
#endif // !defined(AFX_14BEC153_17B9_47BE_845F_71A27BF26B59__INCLUDED_)
解析设备信息
(1)主函数
#ifdef 1//设为1,执行解析硬件的licence。目的:生成exe,用户运行后,读取当前文件夹下sysInfo_licence.lic,生成加密过的licence文件。连同试用版程序一起发送给用户
/*
功能说明:执行解析硬件的licence,该文件来源于用户处的生成结果
目的:生成exe,用户运行后,读取当前文件夹下sysInfo_licence.lic,
解析出用户电脑信息(不显示出来);生成加密过的licence文件。
连同试用版程序一起发送给用户
*/
#define _CRT_SECURE_NO_WARNINGS
#include "CreateKeyLicence.h"
//#include "Run.h"
//#include "AddDll.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <ctime>
#include <cstdio>
using namespace std;
void main()
{
ReCreateKeyLicenceToCustomer("dongkangle", 120);//分别为密钥和使用时间(天)
}
#endif // 1
(2)#include "CreateKeyLicence.h"
#pragma once
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <ctime>
#include <cstdio>
#include "Encode.h"
using namespace std;
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
void base64EncodeString(const char *textToEncode, char *buffer)
{
base64_encodestate state;
base64_init_encodestate(&state);
int numberOfBytesEncoded = base64_encode_block(textToEncode, strlen(textToEncode), buffer, &state);
numberOfBytesEncoded += base64_encode_blockend(buffer + numberOfBytesEncoded, &state);
buffer[numberOfBytesEncoded] = '\0';
}
int ReCreateKeyLicenceToCustomer(string strKey, int usingTime)//读取去掉所以换行符的硬件信息licence
{
//读取用户发回的硬件信息licence
char readBuffer0[128] = "";
char readBuffer1[128] = "";
char readBuffer2[128] = "";
char readBuffer3[128] = "";
char readBuffer4[128] = "";
char readBuffer5[128] = "";
char readBuffer6[128] = "";
char readBuffer7[128] = "";
char readBuffer8[128] = "";
char readBuffer9[128] = "";
const char *inputFilename = "sysInfo_licence.lic";
FILE *inputFile = fopen(inputFilename, "rb");
if (inputFile)
{
while (!feof(inputFile))
{
fgets(readBuffer0, 128, inputFile); //读第1行KeyLicenceFile:
fgets(readBuffer1, 128, inputFile); //读第2行
fgets(readBuffer2, 128, inputFile); //读第3行 mac的字符个数 (方便解析使用)
fgets(readBuffer3, 128, inputFile); //读第4行 cpuid的字符个数 (方便解析使用)
fgets(readBuffer4, 128, inputFile); //读第5行 time的字符个数 (方便解析使用)
fgets(readBuffer5, 128, inputFile); //读第6行 key的字符个数 (方便解析使用)、
fgets(readBuffer6, 128, inputFile); //读第7行// 空格(标志行)。
}
fclose(inputFile);
}
else
printf("Cannot open file: %s\n", inputFilename);
//进行加密工作
char KeyreadBuffer1[128] = "";
char KeyreadBuffer2[128] = "";
char KeyreadBuffer3[128] = "";
char KeyreadBuffer4[128] = "";
char KeyreadBuffer5[128] = "";
char KeyreadkeySize[128] = "";
char KeyreadBuffer6[128] = "";
char KeyreadBuffer7[128] = "";
char KeyreadBuffer8[128] = "";
char KeyreadBuffer9[128] = "";
char KeyreadBuffer10[128] = "";
char UseingTimeStr[128] = "";
int keySizeNumb = strKey.size();
string keySize = to_string(keySizeNumb);
string UseingTime = to_string(usingTime);//使用时间的int转string
base64EncodeString(readBuffer1, KeyreadBuffer1);//对mac的字符个数 加密
base64EncodeString(readBuffer2, KeyreadBuffer2);//对mac的字符个数 加密
base64EncodeString(readBuffer3, KeyreadBuffer3);//对cpu的字符个数 加密
base64EncodeString(keySize.data(), KeyreadkeySize);//对key的字符个数 加密
base64EncodeString(UseingTime.data(), UseingTimeStr);//对key的字符个数 加密
base64EncodeString(readBuffer4, KeyreadBuffer4);//对time的字符个数 加密
base64EncodeString(readBuffer5, KeyreadBuffer5);//对time的字符个数 加密
base64EncodeString(readBuffer6, KeyreadBuffer6);//对mac 加密
base64EncodeString((strKey).data(), KeyreadBuffer9); //对key 加密
//返回新的keylicence.lic
ofstream OutFile("key_licence_Key_out_V1.0.lic"/*,fstream::out*/); //利用构造函数创建txt文本,并且打开该文本
if (OutFile)
{
OutFile << "Key_V1.0:" << "\n" << KeyreadBuffer1 << KeyreadBuffer2 << KeyreadBuffer3 << KeyreadkeySize << UseingTimeStr << KeyreadBuffer4 << KeyreadBuffer5 << KeyreadBuffer6 << KeyreadBuffer9;
OutFile.close(); //关闭文件
return 0;//成功,返回0
}
else
{
return 6;//文件创建失败,或者打不开(创建时,默认是会判断是否存在,如果不存在,自动创建的)
}
return 0;
}
(3)#include "Encode.h"
/*
cencode.h - c header for a base64 encoding algorithm
This is part of the libb64 project, and has been placed in the public domain.
For details, see http://sourceforge.net/projects/libb64
*/
#ifndef BASE64_CENCODE_H
#define BASE64_CENCODE_H
typedef enum
{
step_A, step_B, step_C
} base64_encodestep;
typedef struct
{
base64_encodestep step;
char result;
int stepcount;
} base64_encodestate;
void base64_init_encodestate(base64_encodestate* state_in);
char base64_encode_value(char value_in);
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
#endif /* BASE64_CENCODE_H */
代码附加验证机制
(1)主函数测试
#ifdef 1 //设为1;解析
/*
功能说明:在自己的软件系统中,加入以下代码,
此时,软件就在用户电脑上运行,因此,软件是可以读取该电脑信息,比对该信息和解析出来的是否一致,
如果一致,说明就是用户指定的电脑没
如果不一致,用户无法使用该软件
*/
#define _CRT_SECURE_NO_WARNINGS
//#include "GetSYSInfo.h"
//#include "CreateKeyLicence.h"
//#include "Run.h"
#include "AddDll.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <ctime>
#include <cstdio>
using namespace std;
void main()
{
/*
licence文件读取失败, 返回1
Mac获取失败, 返回2
cpu获取失败, 返回3
mac长度有误失败, 返回4
CPU长度有误失败, 返回5
time长度有误失败, 返回6
mac比对失败 , 返回7
cpu比对失败 , 返回8
licence时间格式错误; 返回9,
系统时间格式错误; 返回10,
剩余时间充裕, 返回11,
剩余时间不足; 剩余天数,返回负数:
*/
int isOk = DecodeKeyLicenceInMyCode();
switch (isOk) {
case 1:
cout << "licence文件读取失败 " << endl; break;
case 2:
cout << "Mac获取失败 " << endl; break;
case 3:
cout << "cpu获取失败 " << endl; break;
case 4:
cout << "mac长度有误失败 " << endl; break;
case 5:
cout << "CPU长度有误失败 " << endl; break;
case 6:
cout << "time长度有误失败 " << endl; break;
case 7:
cout << "mac比对失败 " << endl; break;
case 8:
cout << "cpu比对失败 " << endl; break;
case 9:
cout << "licence时间格式错误 " << endl; break;
case 10:
cout << "系统时间格式错误 " << endl; break;
case 11:
cout << "剩余时间充裕 " << endl; break;
default:
int RemainingTime = isOk; cout << RemainingTime << endl;
break;
}
system("pause");
}
#endif // 1
(2)#include "AddDll.h"
_declspec(dllimport) int DecodeKeyLicenceInMyCode();
总结
项目的源码:
链接:https://pan.baidu.com/s/1SsD0H7TR_chbUkkov4Sd8A
提取码:xv7b
复制这段内容后打开百度网盘手机App,操作更方便哦
使用代码如下:
链接:https://pan.baidu.com/s/1crly94aRtcBQKFjyQsFjEg
提取码:krl4
复制这段内容后打开百度网盘手机App,操作更方便哦