ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

C/C++:Windows获取电脑机器指纹

2019-03-07 22:53:47  阅读:1793  来源: 互联网

标签:name get Windows 指纹 buffer C++ 序列号 UUID


介绍

很多时候我们需要为一台Windows设备生成一个机器指纹来标识一台设备。当然标识设备最好的是与硬件相关的标识,应该硬件一般不会被改变。笔者参考了获取设备唯一标识这篇博客。笔者将使用下面几个字段进行机器指纹的生成。

  1. 主板UUID
    wmic csproduct get UUID
    唯一值,缺陷并不是所有的厂商都提供UUID(可以使用)
  2. CPUID
    wmic cpu get processorid
    同一批次的PC,CPUID可能一样(可以使用)
  3. BIOS序列号
    wmic bios get serialnumber
    刷了BIOS系统可能导致BIOS序列号变动(刷BIOS概率很小,可以使用)
  4. 硬盘序列号
    wmic diskdrive get serialnumber
    多块硬盘,更换硬盘(概率较小,可以使用)
  5. 网卡MAC地址
    网卡更换,MAC地址易被更改 作为硬件不可靠(不建议使用)

代码

这里我们采用的策略是:主板UUID存在,就使用主板UUID生成机器指纹。主板UUID不存在,使用CPUID、BIOS序列号、硬盘序列号生成机器指纹。这里的散列算法用的标准库中自带。

#include <Windows.h>
#include <string>
#include <list>
#include <iostream>
#include <functional>

using namespace std;
#define BUFFER_SIZE 128

bool getDevcieInfo(char* cmd,list<string> &resultList) {
    char buffer[BUFFER_SIZE];
	bool ret = false;
    FILE* pipe = _popen(cmd, "r"); //打开管道,并执行命令 
    if (!pipe)
          return ret;                     
    
	char *name[20] = {"UUID","ProcessorId","SerialNumber"};
	int len0 = strlen(name[0]),len1 = strlen(name[1]),len2 = strlen(name[2]);
	bool isOk = false;
    while(!feof(pipe)) 
	{
		if(fgets(buffer, BUFFER_SIZE, pipe))
		{
			if( strncmp(name[0],buffer,len0) == 0 
				|| strncmp(name[1],buffer,len1) == 0 
				|| strncmp(name[2],buffer,len2) == 0 ) // 能够正确获取信息
			{
				isOk = true;
				continue;
			}
            if( isOk ==  false 
				|| strcmp("\r\n",buffer) == 0 ) //去掉windows无用的空行
			{
				continue;
			}
			ret = true;
			resultList.push_back(string(buffer));
        }
    }
    _pclose(pipe); // 关闭管道 
    return ret; 
}


string getDeviceFingerPrint(){
    list<string> strList;
	list<string>::iterator it;
	hash<string> str_hash;
	size_t num ;
	char tmp[11] = {0};
	
	// 主板UUID存在,就使用主板UUID生成机器指纹
    if( getDevcieInfo("wmic csproduct get UUID",strList)
		&& (*strList.begin()).compare("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF\r\n") != 0)
	{
		//cout << *strList.begin();
		//cout << str_hash(*strList.begin()) << endl;
		num = str_hash(*strList.begin());
		sprintf(tmp,"%u",num);
		//cout << string(tmp) << endl;
		return string(tmp);
    }
    
    // 主板UUID不存在,使用CPUID、BIOS序列号、硬盘序列号生成机器指纹
	string otherStr("");
	strList.clear();
	if( getDevcieInfo("wmic cpu get processorid",strList) ){
		otherStr.append( *strList.begin() );
    }
	strList.clear();
	if( getDevcieInfo("wmic bios get serialnumber",strList) ){
		otherStr.append( *strList.begin() );
    }
	strList.clear();
	if( getDevcieInfo("wmic diskdrive get serialnumber",strList) ){
		string allDiskNum("");
		// 硬盘可能有多块
		for(it = strList.begin();it != strList.end();it++)
		{
			allDiskNum.append(*it);
		}
		//cout << allDiskNum ;
		//cout << str_hash(allDiskNum) << endl;
		otherStr.append( *strList.begin() );
    }
	cout << str_hash(otherStr) << endl;
	//memset(tmp,0,11);
	num = str_hash(otherStr);
	sprintf(tmp,"%u",num);
	//cout << string(tmp) << endl;
	return string(tmp);
}

void test()
{
	string deviceFingerPrint = getDeviceFingerPrint();
	cout << deviceFingerPrint << endl;
}

int main(int args,char* argv[])
{
	test();
	system("pause");            
	return 0;
}

标签:name,get,Windows,指纹,buffer,C++,序列号,UUID
来源: https://blog.csdn.net/qq_29542611/article/details/88321102

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有