本文提供一套完整的 C++ 實現,用於採集計算機核心硬體的唯一標識信息,生成系統指紋,常用於軟體授權綁定、資產管理、防盜版保護等場景。採集項目包括:
CPUID 指令獲取)所有數據追加存入緩衝區 szSystemInfo[4096],長度記錄於 uSystemInfoLen,最終可作為唯一 Key 使用。
調用 GetAdaptersInfo 兩次:首次獲取所需緩衝區大小,二次分配內存獲取完整鏈表。遍歷 IP_ADAPTER_INFO 結構,拷貝 Address 字段(長度 AddressLength)。注意:MAC 可通過註冊表修改,非絕對不可變。
僅支援 Windows NT 內核(2000/XP/2003+)。嘗試兩種方式:
\\.\ScsiX:,發送 IOCTL_SCSI_MINIPORT_IDENTIFY 控制碼,解析 IDSECTOR 結構中的 sSerialNumber(偏移 20 字節)與 sModelNumber(偏移 40 字節)。\\.\PhysicalDriveX,先 DFP_GET_VERSION 獲取設備映射,再發送 DFP_RECEIVE_DRIVE_DATA (0x0007c088) 配合 IDE_ATA_IDENTIFY (0xEC) 或 IDE_ATAPI_IDENTIFY (0xA1) 獲取同樣數據。兩種方式均提取序列號與型號,去除尾部空格後追加到緩衝區。
使用內聯彙編執行 CPUID 指令:
__try {
_asm {
mov eax, 0; cpuid; // 廠商字符串 -> EBX, EDX, ECX
mov dword ptr szCpu[0], ebx;
mov dword ptr szCpu[4], edx;
mov dword ptr szCpu[8], ecx;
mov eax, 1; cpuid; // 特徵標識 -> EDX
mov uCpuID, edx;
}
} __except(EXCEPTION_EXECUTE_HANDLER) { bException = TRUE; }
若無異常,將 uCpuID (4 字節) 與廠商字符串 (12 字節) 依次追加。
最硬核部分:映射物理內存 0x000F0000 - 0x000FFFFF (64KB BIOS 影子區)。
ntdll.dll 導出的 Native API:ZwOpenSection、ZwMapViewOfSection、ZwUnmapViewOfSection。\Device\PhysicalMemory,映射至當前進程地址空間(基址 ba)。0xEC71,格式如 07/08/2002-i845G-ITE8712-JF69VD0CC-00(第 2/5 字符為 '/')。0xF478,格式如 AMI: 51-2300-000000-00101111-030199-(第 2/7 字符為 '-')。0x6577, 0x7196, 0x7550,格式如 NITELT0.86B.0044.P11.9910111055(第 7/11 字符為 '.')。匹配成功則拷貝該字符串至緩衝區,最後解除映射。
文中完整列出了 IDSECTOR, DRIVERSTATUS, SENDCMDOUTPARAMS, SRB_IO_CONTROL, IDEREGS, SENDCMDINPARAMS, GETVERSIONOUTPARAMS, UNICODE_STRING, OBJECT_ATTRIBUTES 等結構,以及函數指針類型 ZWOS, ZWMV, ZWUMV,為直接調用 Native API 提供了完整聲明。