如何用C++去获取硬盘序列号和MAC地址并绑定电脑?

在程序开发中,为了让自己的程序只能在在某个指定电脑上运行,一旦被拷贝到其它电脑上时便无法使用,这样做的目的是保护开发者的劳动成果不被窃取。
一般电脑的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地址和硬盘序列号,然后按一定的规则(算法加密)组合,与程序中嵌入的"锁"进行比对。如果是程序已经被换到其它电脑上,则程序无法打开。当然,也可以将“锁”事先写入数据库中,然后每次打开后读取数据库进行比对。

在C/C++获取计算机的硬盘序列号和显卡序列号是一个稍微复杂的任务,因为C/C++本身并没有提供直接的函数或API来获取这些信息。以下是一种可能的实现方式: 获取硬盘序列号: 在Windows系统上,你可以使用WMI接口来获取硬盘序列号。具体来说,可以使用`Win32_DiskDrive`类和`SerialNumber`属性来获取硬盘序列号。你可以使用C/C++调用WMI接口的方式来实现。 在Linux系统上,你可以通过读取设备文件`/dev/sd*`来获取硬盘序列号。具体来说,你可以打开设备文件,然后使用`HDIO_GET_IDENTITY` ioctl命令来获取硬盘的身份信息,其中包括序列号获取显卡序列号: 在Windows系统上,你可以使用WMI接口来获取显卡序列号。具体来说,可以使用`Win32_VideoController`类和`PNPDeviceID`属性来获取显卡的唯一标识符。同样,你可以通过C/C++调用WMI接口的方式来实现。 在Linux系统上,你可以通过读取显卡设备文件或者执行特定命令来获取显卡信息。具体的实现方式可能因为显卡类型和操作系统的差异而有所不同。你可以尝试使用命令行工具如`lspci`或者读取设备文件`/sys/class/drm/card*/device/uevent`来获取显卡信息。 请注意,以上提到的方法可能需要特权或系统级的操作,并且在不同的操作系统上实现方式可能有所差异。在实际应用中,建议先了解目标平台的相关文档和API,以确定最适合你的环境的方法来获取硬盘序列号和显卡序列号
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值