如何通过设备驱动获取文件版本?内核级调用及函数用法咨询
内核态获取二进制文件产品版本的方案
首先直接给你明确结论:你绝对不能在内核驱动里直接调用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结构解析与资源定位:
- 从DOS头跳转到NT头,定位PE文件的核心结构
- 遍历节表找到
.rsrc资源节 - 递归遍历资源目录,定位到
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
相关产品推荐
相关产品推荐

