在程序开发中,为了让自己的程序只能在在某个指定电脑上运行,一旦被拷贝到其它电脑上时便无法使用,这样做的目的是保护开发者的劳动成果不被窃取。
一般电脑的IP地址是可以修改的,因此不建议使用IP去绑定某个电脑。我们可以使用硬盘序列号和MAC的组合作为绑定,如果想要更加难以破解,则可将二者进行算法加密,生成注册码,最终用于程序的保护。那么具体该如何做呢?下面将一步步给出代码。
1.获取硬盘序列号
#include "stdafx.h"
#include <WinSock2.h>
#include <Windef.h>
#include <atlbase.h>
#include <atlconv.h>
#include <IPHlpApi.h>
#include <algorithm>
#pragma comment(lib,""Iphlpapi.lib)
#pragma comment(lib,""ws2_32.lib)
#pragma comment(lib,""netapi32.lib)
using namespace std;
BOOL GetSerialNum(string& pSerialNum)
{
HANDLE hFile = createFile(_T("\\\\.\\PHYSICALDRIVE0"),0,FILE_SHARE_READ|FILE_SHARE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DWORD retn;
static BYTE buffer[0x1000];
STORAGE_DEVICE_DESCRIPTOR* descriptor = (STORAGE_DEVICE_DESCRIPTOR*)buffer;
STORAGE_PROPERTY_QUERY p = {StorageDeviceProperty, PropertyStandarQuery};
if(!DeviceIoControl(hFile,IOCTL_STORAGE_QUERY_PROPERTY,&p,sizeof(p),buffer,sizeof(buffer),&retn,0));
{
return FALSE;
}
if(descriptor->SerialNumberOffset > 0)
{
char Serial[256];
BYTE* data;
data = buffer + descriptor->SerialNumberOffset;
sprintf_s(Serial,256,"%s",data);
string SerialNum = Serial;
//删除硬盘序列号两端的空格
SerialNum.erase(0,SerialNum.find_first_not_of(" "));
SerialNum.erase(SerialNum.find_last_not_of(" ")+1);
pSerialNum = SerialNum;
}
return TRUE;
}
2.获取MAC地址
int _tmain(int argc, _TCHAR* argv[])
{
//在主程序中先获取硬盘序列号
string pSerialNo_In = "";
if(GetSerialNum(pSerialNo_In) == FALSE)
{
return -1;
}
if(pSerialNo_In == "")
{
return -1;
}
//开始获取MAC地址
char mac[128];
string getMac_key ;
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
ULONG ulOutBufLen;
pAdapterInfo = (PIP_ADAPTER_INFO)malloc(sizeof(PIP_ADAPTER_INFO));
ulOutBufLen = sizeof(PIP_ADAPTER_INFO);
if(GetAdaptersInfo(pAdapterInfo ,&ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo);
pAdapterInfo = (PIP_ADAPTER_INFO*)malloc(ulOutBufLen);
}
if((dwRetVal = GetAdaptersInfo(pAdapterInfo ,&ulOutBufLen)) == NO_ERROR)
{
pAdapter = pAdapterInfo;
if(pAdapter)
{
sprintf(mac,128,"%02x-%02x-%02x-%02x-%02x-%02x",pAdapter->Adress[0],pAdapter->Adress[1],pAdapter->Adress[2],pAdapter->Adress[3],pAdapter->Adress[4],pAdapter->Adress[5]);
getMac_key = mac;
}
}
//拼接MAC地址和硬盘序列号(也可以用算法加密),这里只是举例
getMac_key = getMac_key + "-" + pSerialNo_In;
//此变量为写死在程序中的MAC地址和硬盘序列号(相当于一把锁)
string target_lock = "17-66-DB-3E-F8-52-Z8AJDH87";
transform(getMac_key .begin(),getMac_key .end(),getMac_key .begin(),::toupper); //小写转大写
if(target_lock != getMac_key)
{
//如果锁和钥匙不匹配,则返回,不能进入下面的程序
return -1;
}
/***********************************
我们的程序
************************************/
return 0;
}
程序每次开启后,都会先获取MAC地址和硬盘序列号,然后按一定的规则(算法加密)组合,与程序中嵌入的"锁"进行比对。如果是程序已经被换到其它电脑上,则程序无法打开。当然,也可以将“锁”事先写入数据库中,然后每次打开后读取数据库进行比对。