You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过设备驱动获取文件版本?内核级调用及函数用法咨询

内核态获取二进制文件产品版本的方案

首先直接给你明确结论:你绝对不能在内核驱动里直接调用GetFileVersionInfo——这个是kernel32.dll导出的用户态API,内核环境没有对应的函数实现和用户态上下文支撑,强行调用只会直接触发系统崩溃(BSOD)。

下面给你两种实用的内核级解决方案,按需选择:

方案一:纯内核态手动解析PE版本资源

这是最直接的内核原生方案,核心思路是自己动手解析PE文件中的VS_VERSION_INFO资源块,提取产品版本信息。

大致步骤拆解:

  • 路径格式转换:内核态文件操作必须用NT风格路径,比如把C:\Windows\System32\Notepad.exe转成\??\C:\Windows\System32\Notepad.exe
  • 打开目标文件:调用ZwCreateFile获取文件句柄,记得申请FILE_READ_DATA、SYNCHRONIZE这类必要权限
  • 映射文件到内核内存:通过ZwCreateSection和ZwMapViewOfSection把文件内容映射到内核可访问的地址空间
  • PE结构解析与资源定位:
    1. 从DOS头跳转到NT头,定位PE文件的核心结构
    2. 遍历节表找到.rsrc资源节
    3. 递归遍历资源目录,定位到RT_VERSION类型下的VS_VERSION_INFO资源块
  • 提取版本信息:解析VS_FIXEDFILEINFO结构体,其中dwProductVersionMS和dwProductVersionLS字段就是产品版本的数值,可以拆分为主版本、次版本、构建号、修订号

给你一段简化的核心逻辑代码示例:

// 假设已成功将文件映射到pFileBase地址
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBase;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)pFileBase + pDosHeader->e_lfanew);

// 遍历节表找资源节
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);
for (int i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSectionHeader++) {
    if (strcmp((char*)pSectionHeader->Name, ".rsrc") == 0) {
        // 定位资源根目录
        PIMAGE_RESOURCE_DIRECTORY pResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)pFileBase + pSectionHeader->VirtualAddress);
        // 省略遍历资源目录查找RT_VERSION和VS_VERSION_INFO的细节代码
        // 找到后解析版本信息
        PVS_FIXEDFILEINFO pFixedInfo = ...;
        ULONG major = HIWORD(pFixedInfo->dwProductVersionMS);
        ULONG minor = LOWORD(pFixedInfo->dwProductVersionMS);
        ULONG build = HIWORD(pFixedInfo->dwProductVersionLS);
        ULONG revision = LOWORD(pFixedInfo->dwProductVersionLS);
        DbgPrint("产品版本:%lu.%lu.%lu.%lu\n", major, minor, build, revision);
        break;
    }
}

方案二:借助用户态进程间接调用GetFileVersionInfo

如果不想折腾复杂的PE资源解析,可以让驱动和用户态进程配合,间接使用GetFileVersionInfo。

步骤如下:

  • 驱动创建或打开一个信任的用户态辅助进程(比如用ZwCreateProcess)
  • 通过共享内存或者IOCTL把目标文件路径传递给用户态进程
  • 用户态进程调用GetFileVersionInfoSize、GetFileVersionInfo、VerQueryValue这一套API获取产品版本
  • 用户态进程把解析好的版本信息再通过共享内存或IOCTL返回给驱动

这种方法的优势是不用自己处理繁琐的资源解析逻辑,但缺点是增加了跨态交互的复杂度,还要注意权限和安全问题,比如避免被恶意进程劫持利用。

关键注意事项

  • 内核态操作文件一定要严谨处理错误(比如文件不存在、权限不足),稍有不慎就会导致系统不稳定
  • 文件映射后要记得及时解除映射、关闭句柄,避免内存泄漏
  • 针对系统核心文件(比如Notepad.exe),要注意文件锁定或防护机制,选择合适的打开权限

内容的提问来源于stack exchange,提问作者MrLister

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:51:29