获取CPU ID ,disk ID, MAC ID (windows ARM linux Mac)

时间:2021-10-29 06:47:38

windows

命令行获取CPU ID,可以用ShellExecute

wmic cpu get processorid
ProcessorId
BFEBFBFF000506E3

开源库: 查询CPU信息 . 包括ARM Mac windows

qemu

https://www.qemu.org/

读取硬盘序列号

获取CPU的ID

#include <intrin.h>    // 所有Intrinsics函数

//64位程序,微软不支持内嵌汇编指令
//https://blog.csdn.net/chlk118/article/details/51218964
//微软推出了__cpuid和__cpuidex函数替代了汇编指令,获取 __cpuid厂商,family,CPU名称的代码 同一个批次的CPU DeviceID 都是 BFEBFBFF000506E3
所以获取意义不大!!!!!!!! void GetCPUID()
{
char pvendor[16];
INT32 dwBuf[4]; __cpuid(dwBuf, 0);
*(INT32*)&pvendor[0] = dwBuf[1]; // ebx: 前四个字符
*(INT32*)&pvendor[4] = dwBuf[3]; // edx: 中间四个字符
*(INT32*)&pvendor[8] = dwBuf[2]; // ecx: 最后四个字符
pvendor[12] = '\0'; __cpuid(dwBuf, 0x1);
int family = (dwBuf[0] >> 8) & 0xf; char pbrand[64];
__cpuid(dwBuf, 0x80000000);
if (dwBuf[0] < 0x80000004)
{
return;
} __cpuid((INT32*)&pbrand[0], 0x80000002); // 前16个字符
__cpuid((INT32*)&pbrand[16], 0x80000003); // 中间16个字符
__cpuid((INT32*)&pbrand[32], 0x80000004); // 最后16个字符
pbrand[48] = '\0'; printf("get cpuid=");
printf(pvendor);
printf("\n");
printf(pbrand);
printf("\n"); __cpuidex(dwBuf, 1, 1);
char szTmp[33] = { NULL };
sprintf_s(szTmp, "%08X%08X", dwBuf[3], dwBuf[0]);
printf(szTmp);
printf("\n"); sprintf_s(szTmp, "%08X", family );
printf(szTmp);
} 输出
get cpuid=GenuineIntel
Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
BFEBFBFF000506E3
00000006
-----------------
//32位 //首先说明,CPU序列号并不是全球唯一的,以Intel为例,其不同型号的CPU序列号肯定不同,但不保证同型号的CPU序列号也各不相同,但据说P3后都是全球唯一的,没有详细考证。
//CPU序列号有一个好处就是非常难以修改,至少目前还没听说。将CPU ID 和MAC id 、硬盘id组合起来生成软件序列号,可以大大增加序列号的安全性。(后两者都可以通过软件方法修改)。
string GetCPUID()
{
char cTemp[128]; string CPUID;
unsigned long s1, s2;
unsigned char vendor_id[] = "------------";
char sel;
sel = '1';
string VernderID;
string MyCpuID, CPUID1, CPUID2;
switch (sel)
{
case '1':
__asm {
xor eax, eax //eax=0:取Vendor信息
cpuid //取cpu id指令,可在Ring3级使用
mov dword ptr vendor_id, ebx
mov dword ptr vendor_id[+4], edx
mov dword ptr vendor_id[+8], ecx
} VernderID = (char)vendor_id;
VernderID += "-";
__asm {
mov eax, 01h //eax=1:取CPU序列号
xor edx, edx
cpuid
mov s1, edx
mov s2, eax
}
sprintf_s(cTemp, "%08X%08X", s1, s2);
CPUID1 = cTemp; __asm {
mov eax, 03h
xor ecx, ecx
xor edx, edx
cpuid
mov s1, edx
mov s2, ecx
} sprintf_s(cTemp, "%08X%08X", s1, s2);
CPUID2 = cTemp;
break; case '2':
{
__asm {
mov ecx, 119h
rdmsr
or eax, 00200000h
wrmsr
}
}
printf("CPU id is disabled.");
break;
}
MyCpuID = CPUID1 + CPUID2;
CPUID = MyCpuID; printf(CPUID.c_str());
return CPUID;
}
输出:
BFEBFBFF000506E3 string disk_id()
{
string id;
char Name[MAX_PATH];
DWORD serno;
DWORD length;
DWORD FileFlag;
char FileName[MAX_PATH];
BOOL Ret;
Ret = GetVolumeInformationA("c:\\", Name, MAX_PATH, &serno, &length, &FileFlag, FileName, MAX_PATH);
if (Ret)
{
id = std::to_string(serno);
}
printf("hard Disk id = ");
printf(id.c_str()); printf(" \n ");
return id;
} 输出:
hard Disk id = 681865520

生成可在 x86 和 cpuid 上使用的 x64 指令。 本指令可查询处理器,以获取有关支持的功能和 CPU 类型的信息。

https://docs.microsoft.com/zh-cn/cpp/intrinsics/cpuid-cpuidex



// InstructionSet.cpp
// Compile by using: cl /EHsc /W4 InstructionSet.cpp
// processor: x86, x64
// Uses the __cpuid intrinsic to get information about
// CPU extended instruction set support. #include <iostream>
#include <vector>
#include <bitset>
#include <array>
#include <string>
#include <intrin.h> class InstructionSet
{
// forward declarations
class InstructionSet_Internal; public:
// getters
static std::string Vendor(void) { return CPU_Rep.vendor_; }
static std::string Brand(void) { return CPU_Rep.brand_; } static bool SSE3(void) { return CPU_Rep.f_1_ECX_[0]; }
static bool PCLMULQDQ(void) { return CPU_Rep.f_1_ECX_[1]; }
static bool MONITOR(void) { return CPU_Rep.f_1_ECX_[3]; }
static bool SSSE3(void) { return CPU_Rep.f_1_ECX_[9]; }
static bool FMA(void) { return CPU_Rep.f_1_ECX_[12]; }
static bool CMPXCHG16B(void) { return CPU_Rep.f_1_ECX_[13]; }
static bool SSE41(void) { return CPU_Rep.f_1_ECX_[19]; }
static bool SSE42(void) { return CPU_Rep.f_1_ECX_[20]; } static bool SSE(void) { return CPU_Rep.f_1_EDX_[25]; }
static bool SSE2(void) { return CPU_Rep.f_1_EDX_[26]; } static bool AVX2(void) { return CPU_Rep.f_7_EBX_[5]; } static bool AVX512F(void) { return CPU_Rep.f_7_EBX_[16]; } static bool AVX512PF(void) { return CPU_Rep.f_7_EBX_[26]; }
static bool AVX512ER(void) { return CPU_Rep.f_7_EBX_[27]; }
static bool AVX512CD(void) { return CPU_Rep.f_7_EBX_[28]; }
static bool SHA(void) { return CPU_Rep.f_7_EBX_[29]; } static bool PREFETCHWT1(void) { return CPU_Rep.f_7_ECX_[0]; }
......................... Output>>>>>>> GenuineIntel
Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz AES supported
AVX supported
AVX2 not supported
AVX512CD not supported
AVX512ER not supported
AVX512F not supported
AVX512PF not supported
SHA not supported
SSE supported
SSE2 supported
SSE3 supported
SSE4.1 supported
SSE4.2 supported
SSE4a not supported
SSSE3 supported

dlib 也有封装的库,来测试指令集(各个平台的)


arm

STM32F4(读取芯片ID)

唯一设备标识符适合:
● 用作序列号(例如 USB 字符串序列号或其它终端应用程序)
● 在对内部 Flash 进行编程前将唯一 ID 与软件加密原语和协议结合使用时用作安全密钥以提高 Flash 中代码的安全性
● 激活安全自举过程等
96 位的唯一设备标识符提供了一个对于任何设备和任何上下文都唯一的参考号码。用户永远不能改变这些位。
96 位的唯一设备标识符也可以以单字节/半字/字等不同方式读取,然后使用自定义算法连接起来。
基址:0x1FFF7A10 typedef struct
{ uint32_t id[3];
}ChipID; ChipID Get_ChipID(void)
{
ChipID chipid = {0};
chipid.id[0] = *(__I uint32_t *)(0x1FFF7A10 + 0x00);
chipid.id[1] = *(__I uint32_t *)(0x1FFF7A10 + 0x04);
chipid.id[2] = *(__I uint32_t *)(0x1FFF7A10 + 0x08);
return chipid;
}

读取STM32F207/40x的CPU唯一ID(Unique Device ID)号方法

STM32学习之:读取芯片的唯一标识ID

 产品唯一的身份标识的作用:
● 用来作为序列号(例如USB字符序列号或者其他的终端应用);
● 用来作为密码,在编写闪存时,将此唯一标识与软件加解密算法结合使用,提高代码在闪存存储器内的安全性;
● 用来激活带安全机制的自举过程;
96位的产品唯一身份标识所提供的参考号码对任意一个STM32微控制器,在任何情况下都是唯一的。用户在何种情况下,都不能修改这个身份标识。按照用户不同的用法,可以以字节(8位)为单位读取,也可以以半字(16位)或者全字(32位)读取。嘿嘿,要注意大端小端模式 * 函数名:Get_ChipID
* 描述 :获取芯片ID
* 输入 :无
* 输出 :无
* 说明 :96位的ID是stm32唯一身份标识,可以以8bit、16bit、32bit读取
提供了大端和小端两种表示方法 void Get_ChipID(void)
{
#if 1
u32 ChipUniqueID[3];
地址从小到大,先放低字节,再放高字节:小端模式
地址从小到大,先放高字节,再放低字节:大端模式
ChipUniqueID[2] = *(__IO u32*)(0X1FFFF7E8); // 低字节
ChipUniqueID[1] = *(__IO u32 *)(0X1FFFF7EC); //
ChipUniqueID[0] = *(__IO u32 *)(0X1FFFF7F0); // 高字节
printf("######## 芯片的唯一ID为: X-X-X rn",ChipUniqueID[0],ChipUniqueID[1],ChipUniqueID[2]);
//此条语句输出32位
#else //调整了大小端模式,与ISP下载软件的一致
u8 temp[12];
u32 temp0,temp1,temp2;
temp0=*(__IO u32*)(0x1FFFF7E8); //产品唯一身份标识寄存器(96位)
temp1=*(__IO u32*)(0x1FFFF7EC);
temp2=*(__IO u32*)(0x1FFFF7F0);
temp[0] = (u8)(temp0 & 0x000000FF);
temp[1] = (u8)((temp0 & 0x0000FF00)>>8);
temp[2] = (u8)((temp0 & 0x00FF0000)>>16);
temp[3] = (u8)((temp0 & 0xFF000000)>>24);
temp[4] = (u8)(temp1 & 0x000000FF);
temp[5] = (u8)((temp1 & 0x0000FF00)>>8);
temp[6] = (u8)((temp1 & 0x00FF0000)>>16);
temp[7] = (u8)((temp1 & 0xFF000000)>>24);
temp[8] = (u8)(temp2 & 0x000000FF);
temp[9] = (u8)((temp2 & 0x0000FF00)>>8);
temp[10] = (u8)((temp2 & 0x00FF0000)>>16);
temp[11] = (u8)((temp2 & 0xFF000000)>>24);
printf("######## STM32芯片ID为: %.2X%.2X%.2X%.2X-%.2X%.2X%.2X%.2X-%.2X%.2X%.2X%.2X rn",
temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7],temp[8],temp[9],temp[10],temp [11]); //串口打印出芯片ID
#endif
} * 函数名:Get_ChipInfo(void)
* 描述 :获取芯片Flash 大小
* 输入 :无
* 输出 :无
* 说明 :
void Get_ChipInfo(void)
{
uint32_t ChipUniqueID[3];
u16 STM32_FLASH_SIZE;
ChipUniqueID[0] = *(__IO u32 *)(0X1FFFF7F0); // 高字节
ChipUniqueID[1] = *(__IO u32 *)(0X1FFFF7EC); //
ChipUniqueID[2] = *(__IO u32 *)(0X1FFFF7E8); // 低字节
STM32_FLASH_SIZE= *(u16*)(0x1FFFF7E0); //闪存容量寄存器
printf("rn########### 芯片的唯一ID为: %X-%X-%X n",
ChipUniqueID[0],ChipUniqueID[1],ChipUniqueID[2]);
printf("rn########### 芯片flash的容量为: %dK n", STM32_FLASH_SIZE);
printf("rn########### 烧录日期: "__DATE__" - "__TIME__"n");
//输出使用固件库版本号
printf("rn########### 代码固件库版本: V %d.%d.%d n",__STM32F10X_STDPERIPH_VERSION_MAIN,__STM32F10X_STDPERIPH_VERSION_SUB1,__STM32F10X_STDPERIPH_VERSION_SUB2);
}