在 Windows 核心文件上调用 fopen 返回 NULL 指针

Posted

技术标签:

【中文标题】在 Windows 核心文件上调用 fopen 返回 NULL 指针【英文标题】:Calling fopen on Windows core files returns NULL pointer 【发布时间】:2013-02-20 21:42:34 【问题描述】:

我试图通过它们的绝对路径(在其他地方以编程方式确定)打开几个不同的文件,这样我就可以获得它们的 SHA1 哈希*,其中一些是核心 Windows 文件。当我尝试按如下方式打开文件时,fopen() 在某些(但不是全部)文件上返回 NULL(通常文件名是通过 QueryFullProcessImageName 获取的,但我对其进行了硬编码以防万一):

char * filename = "c:\\windows\\system32\\spoolsv.exe";
FILE * currFileRead = fopen(filename, "rb");
if (currFileRead == NULL)

    printf("Failed to open %s, error %s\n", filename, strerror(errno) );

else

    //hashing code

报告的错误是 2:“没有这样的文件或目录”,但显然它们在那里。它也只对某些进程失败,例如 spoolsv.exe 或 winlogon.exe,而 svchost.exe 和 wininint.exe 似乎可以正常打开。

我的程序有管理权限,但我不明白为什么有些进程会失败,而其他进程却可以顺利打开?

*我正在使用来自 LibTomCrypt (http://libtom.org/?page=features) 的方法,该方法是具有许可许可的开源方法。对 sha1_process 的调用需要一个 hash_state(库内部)、一个无符号字符缓冲区和缓冲区的长度。我需要使用 fopen 读取文件以将文件放入内存进行哈希处理。

【问题讨论】:

想看看 GetLastError() 怎么说。您可以使用 GetLastError() 和 FormatMessage() (或手动查找)吗? 在 64 位操作系统上将其更改为 sysnative 而不是 system32。或者构建一个 64 位程序,以便文件重定向不字节。 Fwiw,对可能由 Windows Update 更新的文件计算哈希可能是不明智的。 RonBurk GetLastError 也报告 2,(根据 MSDN)是 ERROR_FILE_NOT_FOUND - 即同样的问题。 HansPassant - 我的程序需要在 32 位和 64 位主机上运行。所以我不能只制作 64 位版本。将其更改为 sysnative 是什么意思? 你被文件系统重定向器发现了。谷歌一下。 【参考方案1】:

因为您的程序是一个 32 位进程,所以当您尝试打开 c:\windows\system32 时,您实际上得到的 c:\windows\syswow64 并不包含所有相同的文件。

您可以使用IsWow64Process 来确定您是否在64 位系统上运行。如果是,可以将路径中的system32 替换为sysnative 来打开实际文件,除非您需要支持Windows 2003 或Windows XP。根据您的情况,您可能需要处理 Windows 文件夹不是 c:\windows 和/或存在其他名为 system32 的文件夹的可能性。

总体而言,拥有单独的 32 位和 64 位版本的应用程序会更加健壮,或者可能只是出现问题的特定部分。如果您不能让用户安装适当的版本,安装程序可以决定安装哪个,或者您可以始终安装两者并让 32 位版本在 64 上运行时自动启动 64 位版本位系统。

【讨论】:

这就是解决方案(Hans Passant 给了我足够的力量让我朝这个方向前进,尽管我还没有找到 IsWow64Process)。鉴于 EnumProcessModules 在 32 位和 64 位二进制文​​件之间存在的问题,我将致力于编写两个单独的二进制文件。谢谢大家【参考方案2】:

拥有管理权限并不总是足够的,因为如果您要打开的文件正在使用中并且正在使用它的程序已锁定它,那么您将无法打开和读取该文件。

【讨论】:

所以,我的理解是我应该能够在几乎所有情况下打开它进行阅读。例如,我可以在记事本中打开这些 .exe 文件之一(尽管结果显然是垃圾),没有任何问题。我似乎无法在 c 中打开它。

以上是关于在 Windows 核心文件上调用 fopen 返回 NULL 指针的主要内容,如果未能解决你的问题,请参考以下文章

fopen 在调用之前打开文件 [关闭]

将控制台应用程序更改为 Windows 应用程序后 fopen 失败

打开文件和关闭文件

库函数文件,创建打开读写删除操作实现

pe框架的路由返文件

php中fopen函数的返回值是啥啊?