我如何获取PC中CPU的序列号?
我如何获取PC中CPU的序列号?
我可以在不使用任何外部库的情况下,提供与此问题有关的最终答案。只需输入以下命令:
wmic bios get serialnumber
这将为您提供PC机箱上的序列号;) (来自Microsoft知识库)
敬礼!
https://en.wikipedia.org/wiki/Pentium_III#Controversy_about_privacy_issues
https://en.wikipedia.org/wiki/CPUID#EAX=3:_Processor_Serial_Number
EAX=3: 处理器序列号 参见:奔腾III § 隐私问题争议
此命令返回处理器的序列号。处理器序列号最初在英特尔奔腾III上引入,但由于隐私问题,该功能不再实现于后续型号(PSN功能标志位始终被清除)。Transmeta的Efficeon和Crusoe处理器也提供此功能。然而,AMD CPU不在任何CPU型号中实现此功能。
#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]);
}//*/
pusha
。支持内联汇编语法的编译器知道你触及了哪些寄存器。而且你直到稍后的汇编块才使用 popa
,所以如果你担心会影响编译器的寄存器,那么你大多数情况下只会让情况变得更糟,而不是更好。(除非 MSVC 不知道 CPUID 写入 EBX?)无论如何,在检查是否支持 CPUID 后,通常应该使用 __cpuid()
内部函数而不是内联汇编。 - Peter Cordes这是一个旧帖子。但我遇到了同样的问题,不过我使用以下逻辑成功解决了问题,而且没有太多的条件限制。
CPU序列号的问题在于它在虚拟化环境下并不总是有效。
我在一组基于Windows的服务器上实现了以下逻辑:
Win32_BIOS
可以提供BIOS的序列号。需要记住的是,如果系统被虚拟化,你可能会得到所有服务器相同的BIOS序列号。
Win32_NetworkAdapter
可以提供MAC地址,可以同时使用。在有多个网络适配器的情况下,你将得到多个MAC地址。
结合这两个ID,在跨越物理和虚拟的6000台服务器集合中,我得到了所有独特的集合。这很容易通过使用ManagementClass
和ManagementObject
来实现。
但是需要注意的是:当你远程获取MO
实例时,对于一个延迟小于5毫秒、速率为10Gbps的光纤网络,这将需要几秒钟以上的时间。因此,如果进行多线程调用收集WMI
数据,需要考虑到这是更像是低优先级的流量,我不希望疯狂地使用网络。
__get_cpuid (unsigned int __level, unsigned int *__eax, unsigned int *__ebx, unsigned int *__ecx, unsigned int *__edx);
#include <cpuid.h>
注意:处理器序列号是在英特尔奔腾III上引入的,但由于隐私问题,此功能不再实现于后续型号。
来源:wikipedia