【问题标题】:Windows native development: debuggee tries to load werkernel.sys from system32Windows 原生开发:debuggee 尝试从 system32 加载 werkernel.sys
【发布时间】:2015-05-21 22:39:16
【问题描述】:

我现在正在研究 Windows Native API,Nt*/Zw* 方法。我下载了 WDK,安装并成功编译了一个应用程序(x64,在 Win 8.1 x64 下,VS2013)。它唯一做的就是调用NtOpenFile()

为了成功编译/链接它,我必须对项目属性(驱动程序模板应用程序)进行以下更改:

  • 从 WDK 添加包含文件夹
  • 从 WDK 添加 Lib 文件夹
  • 告诉链接器使用 ntoskrnl.lib

意外地,在运行调试器时,我收到错误消息“程序无法启动,因为您的计算机中缺少 C:\Windows\SYSTEM32\werkernel.sys。请尝试重新安装程序以解决此问题。 " werkernel.sys 显然存在于 system32\drivers 中。

编辑:需要明确的是,通过双击图标启动应用程序时也会出现上述错误。

此加载发生在我的任何代码之前,我无法在互联网上的任何地方找到任何内容,也无法在相关文件的项目属性中找到任何内容。所以,总而言之,到目前为止,我有以下问题:

  1. 为什么要为我的应用程序加载 werkernel.sys?
  2. 为什么要从 System32 加载?

我知道mklink werkernel.sys drivers\werkernel.sys 是可能的,但感觉我做错了什么。

【问题讨论】:

  • 我正在使用 Visual Studio。我有另一个使用 NtQueryDirectoryInformationFile() 的应用程序(在 C# 中)——一切正常,所以我没想到 C++ 代码会出现任何问题。实际上我想在那个 C# 应用程序中使用 NtOpenFile,但我坚持使用来自 NtCreateFile 的 0xc000000d 响应,所以我决定使用 WDK 来玩弄它,只是为了看看我在托管方面做错了什么。
  • /SUBSYSTEM 选项设置为什么? (项目属性,在链接器、系统、子系统下。)另外,您是否尝试过使用ntdll.lib as documented 而不是 ntoskrnl.lib?
  • 是的,这行得通。谢谢!正如我在下面所写的,我对 NtCreateFile 重定向到 ZwCreateFile 的一般“代理”页面感到困惑。似乎 Zw* 文档说必须链接 ntoskrnl.lib,实际上对于 NT* 函数,必须链接 ntdll.lib。
  • 我相信您会链接到 ntoskrnl.lib 以获得设备驱动程序,并且可能还会链接到本机可执行文件,但它不适合 Win32 应用程序使用。

标签: c++ windows nt-native-api


【解决方案1】:

当我遇到类似问题时,链接 ntdll.lib 而不是 ntoskrnl.lib 对我有用。

【讨论】:

  • 谢谢,这有帮助。我对重定向到ZwOpenFile 的一般 NtOpenFile 页面感到困惑,它告诉我链接 ntkrnl.lib
【解决方案2】:

NtOpenFile 是微软所说的“内部 API”,它不应该用于生产软件,也不应该用于实验或根本,这些功能可能会发生变化在每个 SP 版本或主要 Windows 版本之间。

如果您想在用户模式下打开文件(WDK 和用户模式?不计算...除非您实际上是为 UMDF 编写)建议您使用 OpenFile
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365430(v=vs.85).aspx
或在您的驱动程序中:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff567011(v=vs.85).aspx

tl;dr :不要使用这些旧功能,它们不应该被使用。

微软关于“内部”API 的声明:https://msdn.microsoft.com/en-us/library/bb432200(v=vs.85).aspx

【讨论】:

  • 这是一个相当老的页面,你指的是顺便说一句。 Nt/Zw 函数现在已完美记录。如果您想知道在这种特殊情况下使用本机函数的原因 - 考虑对 NtQueryDirectoryInformationFile() 的 2 次调用需要 0.35 秒,而 FindFirst/FindNext/FindClose 需要 12 秒(是的,12 秒!)。对于 NtOpenFile() 我只希望它能让应用程序更快:)
  • 使用内部 API 不会使您的应用程序更快 - 这是一个非常具有误导性的结论。一些内部函数看起来更快的原因是一个相当令人不安的事实:公共 API 的错误使用。与标准等效项相比,每个 Nt/Zw 调用的时间不会超过几微秒,您的示例几乎可以证明您以错误的方式使用 API。 WINAPI非常很难掌握,只有极少数人真正知道如何正确掌握。哦,你错误地使用了“native”这个词——WINAPI 中没有非本地函数。
  • Microsoft 至少以两种不同的方式使用“本地”一词。其中之一是 Mike 使用它的方式 - 描述作为内核的一部分而不是子系统(例如 Win32)的一部分的函数或直接在内核下而不是在子系统内运行的应用程序。例如,请参阅the /SUBSYSTEM option
  • 其实有点意思;然而,直接调用“本机”函数仍然很容易出错且无用 - 如果您的应用程序运行缓慢 99,9999999999999999999999999% 的时间是您自己的错。一旦他们能够这样做,“本机”API 将被删除,因此在可预见的将来,您的所有应用程序都将不再工作。
  • @Mike:在枚举目录的特殊情况下,您可能应该调查 GetFileInformationByHandleEx。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多