006-获取硬件序列号

获取硬件序列号

我将从跨平台角度系统讲解如何通过C++获取硬件序列号的核心技术,并提供可移植性代码实现。

一、处理器序列号获取

  1. Windows平台
#include <windows.h>
#include <intrin.h>

std::string GetCPUSerial_Win() {
    DWORD cpuInfo[2] = { 0 };
    __cpuid((int*)cpuInfo, 1);
    char cpuSerialNumber[BUFFERLEN];
    std::sprintf(cpuSerialNumber, "%08x-%08x", cpuInfo[0], cpuInfo[1]);
    return std::string(cpuSerialNumber);
}

使用CPUID指令获取完整处理器信息

  1. Linux平台
#include <cpuid.h>
 
std::string GetCPUSerial_Unix() {
    char buffer[128]();
    FILE* pipe = popen("dmidecode -t processor | grep 'ID'", "r");
    fgets(buffer, 128, pipe);
    pclose(pipe);
    return std::string(buffer).substr(5); // 返回类似F3A56F3E-1A格式 
}

通过dmidecode命令获取物理ID

  1. macOS平台
std::string GetCPUSerial_macOS() {
    std::string serial = "";
    FILE *fp = popen("sysctl -n machdep.cpu.brand_string", "r");
    if (fp) {
        char buffer[128];
        while (fgets(buffer, sizeof(buffer), fp)) {
            serial += buffer;
            break;
        }
        pclose(fp);
    }
    return serial;
}

二、内存序列号获取

  1. 跨平台通用方法
// Windows需包含wmi查询代码 
// Linux/macOS:
std::string GetMemorySerial() {
#if defined(_WIN32)
    // WMI查询Win32_PhysicalMemory 
#elif defined(__linux__)
    char buffer[128];
    FILE* pipe = popen("dmidecode -t memory | grep 'Serial Number'", "r");
    fgets(buffer, 128, pipe);
    pclose(pipe);
    return std::string(buffer);
#elif defined(__APPLE__)
    system("system_profiler SPMemoryDataType | grep 'Serial'");
#endif 
    return serial; 
}

内存序列号通常需要系统级权限获取

三、显卡序列号获取

  1. Windows实现
#include <windows.h>
#include <setupapi.h>
 
std::string GetGPUSerial_Win() {
    DISPLAY_DEVICE dd;
    dd.cb  = sizeof(DISPLAY_DEVICE);
    EnumDisplayDevices(NULL, 0, &dd, 0);
    return dd.DeviceID; // 返回PCI\VEN_10DE&DEV_2206格式 
}

通过显示设备枚举获取硬件ID

  1. Linux实现
std::string GetGPUSerial_Linux() {

}

直接从DRM接口读取信息

四、硬盘序列号获取

  1. 跨平台实现框架
std::string GetDiskSerial() {
#if defined(_WIN32)
    // wmic diskdrive get serialnumber
#elif defined(__linux__)
    // udevadm info --query=all --name=/dev/sda | grep ID_SERIAL_SHORT
#elif defined(__APPLE__)
    system("diskutil info disk0 | grep 'Device Identifier'");
#endif 
}

Windows需要管理员权限获取物理序列号

五、完整跨平台代码结构

#include <iostream>
#include <string>
 
class HardwareInfo {
public:
    static std::string GetCPUSerial() {
        #if defined(_WIN32)
            // Windows实现 
        #elif defined(__linux__)
            // Linux实现 
        #elif defined(__APPLE__)
            // macOS实现 
        #endif 
    }
    
    // 其他硬件获取方法同理...
};
 
int main() {
    std::cout << "CPU Serial: " << HardwareInfo::GetCPUSerial() << std::endl;
    // 输出其他硬件信息...
    return 0;
}

六、注意事项

权限要求:Linux/macOS需root权限获取完整信息
硬件差异:虚拟机可能返回非物理硬件ID
RAID阵列:存储设备组RAID后可能无法获取物理序列号
安全策略:Windows需启用WMI服务,macOS需签名后执行
完整代码实现参考来源:。不同平台的具体实现细节可查阅各操作系统的硬件访问API文档。

七、防止篡改

针对硬件信息获取代码防Hook篡改的防护方案,需结合操作系统特性和安全机制设计多层次防御体系。以下从代码防护、运行时检测、系统加固三个维度提供解决方案:

1、核心代码防护策略
  • 关键函数完整性校验
// Windows代码段CRC校验示例
DWORD CalculateFunctionCRC(void* funcAddr, size_t len) {
    DWORD crc = 0;
    for(size_t i=0; i<len; ++i) {
        crc += ((BYTE*)funcAddr)[i] * (i%255 +1);
    }
    return crc;
}

void VerifyCPUIDFunction() {
    const DWORD expectedCRC = 0x12AB34CD; // 预计算的安全哈希值
    DWORD actualCRC = CalculateFunctionCRC(GetCPUSerial_Win, 0x200);
    if(actualCRC != expectedCRC) exit(EXIT_FAILURE); // 检测到篡改立即终止
}

通过计算关键函数内存哈希值,防范Inline Hook注入

  • 系统调用直通技术
// Linux直接调用syscall绕过glibc Hook
std::string SafeDmidecode() {
    syscall(SYS_execve, "/usr/sbin/dmidecode", "-t processor", nullptr); 
    // 绕过可能被Hook的库函数
}

绕过可能被劫持的库函数,直接使用syscall指令

2、运行时环境检测
检测类型Windows实现Linux/macOS实现
调试器检测IsDebuggerPresent()+CheckRemoteDebuggerPresent()组合检测检查/proc/self/status中TracerPid值
内存篡改检测VirtualQuery检查代码段内存保护属性mprotect设置代码段为只读
Hook特征扫描扫描API函数头5字节的JMP指令特征使用dl_iterate_phdr检测PLT Hook
环境完整性校验校验硬件信息获取相关系统文件数字签名验证dmidecode等工具的HASH值

采用多线程定时轮询检测机制,异常时触发熔断逻辑

3、系统级防护加固
  • 权限最小化原则

Windows:为进程配置Mandatory Integrity Control,设置低完整性级别
Linux:通过capabilities机制限制CAP_SYS_RAWIO等敏感权限
macOS:启用SIP(System Integrity Protection)并签名可执行文件

  • 通信加密通道
// 使用TPM模块加密传输
std::string GetEncryptedSerial() {
    std::string raw = GetCPUSerial();
    return TpmEncrypt(raw, TPM_AIK_CERT); // 通过可信平台模块加密
}

结合安全硬件模块实现端到端加密

  • 防御性编程模式
  • 关键数据采用XOR双存储校验
  • 使用std::atexit注册异常清理函数
  • 实现反内存dump的代码自修改技术
4、跨平台防御方案对比
防护维度Windows优势方案Linux优势方案macOS特色机制
API防护Detours库Hook检测LD_PRELOAD环境变量监控dyld插桩检测
内存保护VEH异常处理mprotect+seccompMAP_JIT内存属性
可信执行Device GuardIMA完整性测量架构Secure Enclave
更新策略驱动签名强制验证内核模块签名验证Notarization公证机制

建议采用分层防御架构,组合应用至少3种不同机制的防护方案

5、对抗升级建议
  • 动态混淆技术:每次运行时重构关键代码的指令序列
  • 可信验证链:建立从固件层到应用层的完整信任链验证
  • AI行为分析:通过机器学习模型识别异常Hook模式
  • 硬件绑定:将关键逻辑与TPM/安全芯片绑定

通过上述方案组合实施,可有效对抗90%以上的常规Hook攻击。但需注意,安全防护需持续迭代更新,建议建立自动化攻击模拟测试环境,定期验证防护措施有效性。

完整代码

Github

作者郑天佐
邮箱zhengtianzuo06@163.com
主页http://www.zhengtianzuo.com
githubhttps://github.com/zhengtianzuo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/984258.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GDB调试技巧:多线程案例分析(保姆级)

在软件开发的复杂世界里&#xff0c;高效的调试工具是解决问题的关键利器。今天&#xff0c;我们将深入探讨强大的调试工具 ——GDB&#xff08;GNU Debugger&#xff09;。GDB 为开发者提供了一种深入程序内部运行机制、查找错误和优化性能的有效途径。让我们一同开启 GDB 的调…

OSPF的各种LSA类型,多区域及特殊区域

一、OSPF的LSA类型 OSPF&#xff08;开放最短路径优先&#xff09;协议使用多种LSA&#xff08;链路状态通告&#xff09;类型来交换网络拓扑信息。以下是主要LSA类型的详细分类及其作用&#xff1a; 1. Type 1 LSA&#xff08;路由器LSA Router LSA&#xff09; 生成者&…

JavaScript系列06-深入理解 JavaScript 事件系统:从原生事件到 React 合成事件

JavaScript 事件系统是构建交互式 Web 应用的核心。本文从原生 DOM 事件到 React 的合成事件&#xff0c;内容涵盖&#xff1a; JavaScript 事件基础&#xff1a;事件类型、事件注册、事件对象事件传播机制&#xff1a;捕获、目标和冒泡阶段高级事件技术&#xff1a;事件委托、…

字节跳动C++客户端开发实习生内推-抖音基础技术

智能手机爱好者和使用者&#xff0c;追求良好的用户体验&#xff1b; 具有良好的编程习惯&#xff0c;代码结构清晰&#xff0c;命名规范&#xff1b; 熟练掌握数据结构与算法、计算机网络、操作系统、编译原理等课程&#xff1b; 熟练掌握C/C/OC/Swift一种或多种语言&#xff…

MySQL进阶-关联查询优化

采用左外连接 下面开始 EXPLAIN 分析 EXPLAIN SELECT SQL_NO_CACHE * FROM type LEFT JOIN book ON type.card book.card; 结论&#xff1a;type 有All ,代表着全表扫描&#xff0c;效率较差 添加索引优化 ALTER TABLE book ADD INDEX Y ( card); #【被驱动表】&#xff0…

ai之qwq 32B部署在 linux 与拓展使用在web参考

linux部署 Linux 命令行&#xff1a; curl -fsSL https://ollama.com/install.sh | sh2 将Ollama设置为系统启动时自动运行&#xff08;建议&#xff09; 创建系统用户和用户组 sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollamasudo usermod -a -G ollama $…

景联文科技:以精准数据标注赋能AI进化,构筑智能时代数据基石

在人工智能技术席卷全球的浪潮中&#xff0c;高质量数据已成为驱动AI模型进化的核心燃料。作为全球领先的AI数据服务解决方案提供商&#xff0c;景联文科技深耕数据标注领域多年&#xff0c;以技术为基、以专业为本&#xff0c;致力于为全球客户提供全场景、高精度、多模态的数…

C语言_数据结构总结4:不带头结点的单链表

纯C语言代码&#xff0c;不涉及C 0. 结点结构 typedef int ElemType; typedef struct LNode { ElemType data; //数据域 struct LNode* next; //指针域 }LNode, * LinkList; 1. 初始化 不带头结点的初始化&#xff0c;即只需将头指针初始化为NULL即可 void Init…

IDEA 基础配置: maven配置 | 服务窗口配置

文章目录 IDEA版本与MAVEN版本对应关系maven配置镜像源插件idea打开服务工具窗口IDEA中的一些常见问题及其解决方案IDEA版本与MAVEN版本对应关系 查找发布时间在IDEA版本之前的dea2021可以使用maven3.8以及以前的版本 比如我是idea2021.2.2 ,需要将 maven 退到 apache-maven-3.…

【单片机】ARM 处理器简介

ARM 公司简介 ARM&#xff08;Advanced RISC Machine&#xff09; 是英国 ARM 公司&#xff08;原 Acorn RISC Machine&#xff09; 开发的一种精简指令集&#xff08;RISC&#xff09; 处理器架构。ARM 处理器因其低功耗、高性能、广泛适用性&#xff0c;成为嵌入式系统、移动…

DeepSeek+知识库+鸿蒙,助力鸿蒙高效开发

不知道你们发现没有&#xff0c;就是鸿蒙开发官网&#xff0c;文档也太多太多了&#xff0c;对于新手来说确实头疼&#xff0c;开发者大多是极客&#xff0c;程序的目的是让世界更高效&#xff01;看文档&#xff0c;挺头疼的&#xff0c;毕竟都是理科生。 遇到问题不要慌&…

第十五届蓝桥杯省赛电子类单片机学习过程记录(客观题)

客观试题: 01.典型的BUCK电源电路包含哪些关键器件(ABCD) A. 电容 B. 二极管 C. 电感 D. MOSFET 解析: 典型的 BUCK 电源电路是一种降压型的直流-直流转换电路,它包含以下关键器件: A.电容:电容在电路中起到滤波的作用。输入电容用于平滑输入电压的波动,减少电源噪声对…

uniapp uniCloud引发的血案(switchTab: Missing required args: “url“)!!!!!!!!!!

此文章懒得排版了&#xff0c;为了找出这个bug, 星期六的晚上我从9点查到0点多&#xff0c;此时我心中一万个草泥马在崩腾&#xff0c;超级想骂人&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; uniCloud 不想…

源码:用Python进行电影数据分析实战指南

源码&#xff1a;用Python进行电影数据分析实战指南 原创 IT小本本 IT小本本 2025年03月03日 22:28 北京 接上一篇文章&#xff1a;用Python进行电影数据分析实战指南 1、首先复制csv内容到csv文件中 2、接着创建.py文件复制源码内容 3、运行代码&#xff0c;就可以看到数据…

GHCTF2025--Web

upload?SSTI! import os import refrom flask import Flask, request, jsonify,render_template_string,send_from_directory, abort,redirect from werkzeug.utils import secure_filename import os from werkzeug.utils import secure_filenameapp Flask(__name__)# 配置…

Unity Shader编程】之基础纹理

一&#xff0c;单张纹理 好的&#xff0c;用户想学习Unity Shader中的单张纹理章节。我需要根据提供的搜索结果来整理相关内容。首先&#xff0c;查看搜索结果中的相关部分&#xff0c;特别是‌、‌、‌、‌、‌这几条&#xff0c;因为它们提到了基础纹理、单张纹理的实现方法…

SpringBoot使用注解扫描注册Java Web三大组件

使用注解扫描和注册Java Web三大组件&#xff08;Servlet、Filter、Listener&#xff09;非常方便。 1. Servlet 注册 Servlet 是 Java Web 开发的基础组件&#xff0c;用于处理客户端&#xff08;通常是浏览器&#xff09;发送的 HTTP 请求并生成响应。 Controller是基于 Ser…

STM32F4 UDP组播通信:填一填ST官方HAL库的坑

先说写作本文的原因&#xff0c;由于开项目开发中需要用到UDP组播接收的功能&#xff0c;但是ST官方没有提供合适的参考&#xff0c;使用STM32CubeMX生成的代码也是不能直接使用的&#xff0c;而我在网上找了一大圈&#xff0c;也没有一个能够直接解决的方案&#xff0c;deepse…

JVM - 3.垃圾回收

1.垃圾收集的经典问题 1.哪些内存需要回收2.什么时候回收3.如何回收1.你知道哪几种垃圾回收器&#xff0c;各自的优缺点&#xff0c;重点讲一下cms和g12.JVM GC算法有哪些&#xff0c;目前的JDK版本采用什么回收算法3.G1回收器的回收过程 1.Java中垃圾的定义&#xff08;Garbag…

重构谷粒商城09:人人开源框架的快速入门

谷粒商城09——人人开源框架的快速入门 前言&#xff1a;这个系列将使用最前沿的cursor作为辅助编程工具&#xff0c;来快速开发一些基础的编程项目。目的是为了在真实项目中&#xff0c;帮助初级程序员快速进阶&#xff0c;以最快的速度&#xff0c;效率&#xff0c;快速进阶…