题
如何获取PC中CPU的序列号?
解决方案
根据您在问题中使用的“许可”标签,您可能会得到更好的结果 读取网络MAC地址. 。通过 MAC 地址识别 PC 并不是完全牢不可破的复制保护方法,但有时仍然会使用它。
其他提示
我在没有任何外部库的情况下得到了最终的答案。只需输入以下内容:
wmic BIOS 获取序列号
这将为您提供PCS底盘上的序列号;)(在Microsoft的知识库中找到)
问候!
请记住,现在大多数计算机在出厂时都在 BIOS 中禁用了 CPU ID。看 维基百科上的 CPUID
即使启用了 CPUID,现代处理器中实际上还有可用的序列号吗?我记得当整个序列号问题被提出时,Pentium 3 引起了强烈的抗议。
这是旧线程。但我遇到了同样的问题,但我得到了以下逻辑,没有太多的“如果”、“与”或“但是”。
CPU序列号的问题是它并不总是在虚拟化环境中工作。
我对一组基于 Windows 的服务器执行了以下逻辑:
Win32_BIOS
可以为您提供BIOS的序列号。我们需要记住,如果系统是虚拟化的,您最终可能会为所有服务器提供相同的 BIOS 序列号。
Win32_NetworkAdapter
可以为您提供一个您也可以使用的 MAC。如果您有多个 NIC,您最终将获得多个 MAC。
将这两个 ID 结合起来,我就拥有了跨越物理和虚拟的 6000 台服务器的全部唯一集。使用这个方法实现起来非常简单 ManagementClass
& ManagementObject
.
但需要注意的是:当你试图得到 MO
在远程实例中,在 <5ms 延迟的 10Gbps 光网络上需要几秒钟以上的时间。所以如果你算一下,我在单线程操作上花费了 3 个多小时。由于这更像是低优先级流量,我不想向我的网络发送垃圾邮件以进行收集 WMI
多线程调用的数据。
没有CPU序列ID(PSN;Intel CPU 中奔腾 III 之后的 CPUID edx 位 18“psn”处理器序列号;AMD 芯片中从来没有任何 psn:
https://software.intel.com/en-us/forums/watercooler-catchall/topic/308483 (2005年)
但是,请记住,只有 Pentium III Xeon、Mobile Pentium III 和 Pentium III 处理器支持 Pentium III 处理器引入的处理器序列号功能。没有其他英特尔处理器支持处理器序列号功能
https://en.wikipedia.org/wiki/Pentium_III#Controversy_about_privacy_issues
https://en.wikipedia.org/wiki/CPUID#EAX=3:_Processor_Serial_Number
EAX=3:处理器序列号也请参见:Pentium III § 关于隐私问题的争议
这将返回处理器的序列号。处理器序列号是在 Intel Pentium III 上引入的,但出于隐私考虑,此功能在后续型号上不再实现(PSN 功能位始终被清除)。Transmeta 的 Efficeon 和 Crusoe 处理器也提供此功能。然而,AMD CPU 并未在任何 CPU 型号中实现此功能。
使用CPUZ工具: http://www.cpuid.com/cpuz.php
__get_cpuid (unsigned int __level, unsigned int *__eax, unsigned int *__ebx, unsigned int *__ecx, unsigned int *__edx);
- 标题:
#include <cpuid.h>
笔记: 处理器序列号是在 Intel Pentium III 上引入的,但出于隐私考虑,此功能在后续型号上不再实现。
来源 : 维基百科
Ivy Bridge CPU 及更新版本均包含 PPIN(受保护的处理器识别号)。计算机的固件可以阻止对此功能的访问。
请提供更多详细信息:操作系统、语言。
例如,在 Windows 上,您可以通过使用 WMI 并阅读来获取它 Win32_Processor.ProcessorId.
在Windows中,我确信有一个系统调用,在Linux中,人们可以尝试“sudo lshw”,但大多数内核似乎不支持CPU序列号,初步研究似乎表明,对唯一可识别计算机的普遍愤怒意味着有没有完美的答案。
你想做什么?几乎可以肯定有人以前做过,重复使用或模仿他们所做的事情可能是明智的。
使用正确的寄存器设置执行 CPUID 指令将检索 EAX、EBX、ECX 和 EDX 中的处理器序列号。但是,此功能仅适用于 Pentium 3 及更高版本的处理器。同样,在 Pentium 4 和更新的处理器上,该指令始终在所有 4 个寄存器中返回 0x00000000。更高型号的 Pentium 3 也可能返回 0x00000000。该功能主要旨在复制保护,允许软件链接到特定处理器。它在社区中反响不佳,随之而来的是诉讼。该功能已从最新型号 P3 和所有较新的处理器中删除。出于兼容性原因,该功能出现在较新的处理器中。据传,您可以特别订购具有序列号的处理器,btu 的最低购买量约为 100 万个处理器。有关执行 CPUID 指令之前的具体寄存器设置,请通过其网站查看 Intel 系统程序员 PDF。
还 -
#include <Windows.h>
#include <stdio.h>
#include <xmmintrin.h>
#include <iphlpapi.h>
#include <Rpc.h>
static void GetMACaddress(void);
static void uuidGetMACaddress(void);
int main(){
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
printf("Processors - %d\n" , SysInfo.dwNumberOfProcessors);
DWORD a , b , c , d , e;
DWORD BasicLeaves;
char* VendorID = (char*)malloc(20);
char* message = (char*)malloc(20);
_asm {
pusha
pushfd
pop eax
push eax
xor eax , 0x00200000
push eax
popfd
pushfd
pop ecx
pop eax
xor eax , ecx
mov [a] , eax
}
if(a & 0x00200000){
printf("CPUID opcode supported.\n");
} else {
printf("CPUID opcode not supported, exiting...\n");
return 0;
}
//DWORD* pa = &a[0];
//DWORD* pb = &a[1];
//DWORD* pc = &a[2];
//DWORD* pd = &a[3];
//a[4] = 0;
e = 0;
__asm {
mov eax , 0
cpuid
mov [BasicLeaves] , eax;
mov [b] , ebx;
mov [c] , ecx;
mov [d] , edx;
}
memcpy(&VendorID[0] , &b , 4);
memcpy(&VendorID[4] , &d , 4);
memcpy(&VendorID[8] , &c , 4);
VendorID[12] = 0;
printf("%d Basic Leaves\nVendorID - %s\n" , BasicLeaves , VendorID);
__asm {
mov eax , 1
cpuid
mov [a] , eax;
mov [b] , ebx;
mov [c] , ecx;
mov [d] , edx;
}
if(d & 0x00000001) printf("FPU\n");
if(d & 0x00000200) printf("APIC On-Chip\n");
if(d & 0x00040000) printf("Processor Serial Number Present\n");
if(d & 0x00800000) printf("MMX\n");
if(d & 0x01000000) printf("SSE\n");
if(d & 0x02000000) printf("SSE2\n");
if(d & 0x08000000) printf("Hyperthreading (HTT)\n");
if(c & 0x00000001) printf("SSE3\n");
if(c & 0x00000200) printf("SSSE3\n");
if(c & 0x00080000) printf("SSE4.1\n");
if(c & 0x00100000) printf("SSE4.2\n");
if(c & 0x02000000) printf("AES\n");
__asm {
mov eax , 0x80000000
cpuid
and eax , 0x7fffffff;
mov [a] , eax;
mov [b] , ebx;
mov [c] , ecx;
mov [d] , edx;
}
printf("%d Extended Leaves\n" , a);
printf("Processor Brand String - ");
__asm {
mov eax , 0x80000002
cpuid
mov [a] , eax;
mov [b] , ebx;
mov [c] , ecx;
mov [d] , edx;
}
memcpy(&message[0] , &a , 4);
memcpy(&message[4] , &b , 4);
memcpy(&message[8] , &c , 4);
memcpy(&message[12] , &d , 4);
message[16] = 0;
printf("%s" , message);
__asm {
mov eax , 0x80000003
cpuid
mov [a] , eax;
mov [b] , ebx;
mov [c] , ecx;
mov [d] , edx;
}
memcpy(&message[0] , &a , 4);
memcpy(&message[4] , &b , 4);
memcpy(&message[8] , &c , 4);
memcpy(&message[12] , &d , 4);
message[16] = 0;
printf("%s" , message);
__asm {
mov eax , 0x80000004
cpuid
mov [a] , eax;
mov [b] , ebx;
mov [c] , ecx;
mov [d] , edx;
popa
}
memcpy(&message[0] , &a , 4);
memcpy(&message[4] , &b , 4);
memcpy(&message[8] , &c , 4);
memcpy(&message[12] , &d , 4);
message[16] = 0;
printf("%s\n" , message);
char VolumeName[256]; DWORD VolumeSerialNumber; DWORD MaxComponentLength; DWORD FileSystemFlags; char FileSystemNameBuffer[256];
GetVolumeInformationA("c:\\" , VolumeName , 256 , &VolumeSerialNumber , &MaxComponentLength , &FileSystemFlags , (LPSTR)&FileSystemNameBuffer , 256);
printf("Serialnumber - %X\n" , VolumeSerialNumber);
GetMACaddress();
uuidGetMACaddress();
return 0;
}
// Fetches the MAC address and prints it
static void GetMACaddress(void){
IP_ADAPTER_INFO AdapterInfo[16]; // Allocate information
// for up to 16 NICs
DWORD dwBufLen = sizeof(AdapterInfo); // Save memory size of buffer
DWORD dwStatus = GetAdaptersInfo( // Call GetAdapterInfo
AdapterInfo, // [out] buffer to receive data
&dwBufLen); // [in] size of receive data buffer
//assert(dwStatus == ERROR_SUCCESS); // Verify return value is
// valid, no buffer overflow
PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo; // Contains pointer to
// current adapter info
do {
printf("Adapter MAC Address - %X-%X-%X-%X-%X-%X\n" , pAdapterInfo->Address[0] , pAdapterInfo->Address[1] , pAdapterInfo->Address[2] , pAdapterInfo->Address[3] , pAdapterInfo->Address[4] , pAdapterInfo->Address[5]);
printf("Adapter IP Address - %s\n" , pAdapterInfo->CurrentIpAddress);
printf("Adapter Type - %d\n" , pAdapterInfo->Type);
printf("Adapter Name - %s\n" , pAdapterInfo->AdapterName);
printf("Adapter Description - %s\n" , pAdapterInfo->Description);
uuidGetMACaddress();
printf("\n");
//PrintMACaddress(pAdapterInfo->Address); // Print MAC address
pAdapterInfo = pAdapterInfo->Next; // Progress through
// linked list
} while(pAdapterInfo); // Terminate if last adapter
}
// Fetches the MAC address and prints it
static void uuidGetMACaddress(void)
{
unsigned char MACData[6];
UUID uuid;
UuidCreateSequential( &uuid ); // Ask OS to create UUID
for (int i=2; i<8; i++) // Bytes 2 through 7 inclusive
// are MAC address
MACData[i - 2] = uuid.Data4[i];
printf("UUID MAC Address - %X-%X-%X-%X-%X-%X\n" , MACData[0] , MACData[1] , MACData[2] , MACData[3] , MACData[4] , MACData[5]);
}//*/
您可以使用 CPUID 命令。
我想很多编译器确实提供了上述命令周围的包装器或类似的包装器。这是一个例子
#include <stdlib.h>
#include <string.h>
#include <intrinsics.h>
_CPUID cpuinfo;
int main(void) {
_cpuid(&cpuinfo);
printf("Vendor: %s\n", cpuinfo.Vendor);
return 0;
}
输出:
Vendor: GenuineIntel