【问题标题】:Is DLL loaded in kernel mode or user mode?DLL是在内核模式还是用户模式下加载的?
【发布时间】:2012-07-10 01:15:07
【问题描述】:

我在一次采访中被问到这样一个问题:

在windows中,假设有一个依赖于某些dll的exe,当你启动时 exe,然后会加载依赖的dll,是这些dll吗 加载内核模式还是用户模式?

我不太确定这个问题,没有提到答案 - 你能帮忙解释一下吗?

谢谢。

【问题讨论】:

  • 在这种情况下,我会非常想挑战“单击 exe”会执行它的假设。
  • @BenVoigt 抱歉,我没听清楚,但是“单击 exe”到底有什么问题?
  • 如果我在 Windows 资源管理器中单击一个 exe 文件,它就会被选中。如果我在 Visual Studio 中单击 exe 文件,资源编辑器将打开并显示图标、字符串、菜单和对话框资源。如果我在 Dependency Walker 中单击一个 exe 文件,则会分析依赖的 DLL。只有在其中一种情况下,依赖 DLL 从磁盘读取,并且仅作为数据文件,它们没有“加载”(在 OS 库加载器的意义上)。
  • @BenVoigt 有道理:) 我应该简单地将其改写为“启动 exe”
  • Linux 具有扩展名为 .ko(非必需)的动态可加载内核模块,它们不同于具有扩展名 (.so) 的动态可加载用户库。我不知道 Windows 中是否有类似的区别。但答案将来自类比。

标签: windows dll operating-system


【解决方案1】:

我不是 Windows 内部工作原理的专家,但我知道正确答案是用户模式,因为只有与您的操作系统相关的进程才被允许进入内核空间 http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode

基本上如果不是操作系统进程,就会分配到用户空间。

【讨论】:

  • 这是正确的,但还远远不够。许多操作系统服务也在用户模式下运行。过去可以说驱动程序是内核模式下的可加载组件,但现在甚至有些驱动程序在用户模式下运行。 (也许我们应该将这些称为“设备支持服务”而不是驱动程序,以保持区别。)
  • @BenVoigt 关于驱动程序,我们还可以从 Microsoft 的角度对哪些驱动程序进行数字签名和“安全”以及哪些驱动程序没有进行清晰的区分。用户空间和内核空间的概念并不关心这些实现细节,而是操作系统的基础;这取决于问题是什么以及这次采访的意义所在。
  • 驱动程序签名不会影响驱动程序的加载方式。如果没有签名,您只能在驱动程序进入内核空间之前确认安装。
  • @lzprgmr:DLL 未加载到内核模式。内核模式组件可能有助于加载过程,但这似乎不是问题所要问的。
  • @Ben Voigt:在加载阶段检查签名,没有确认。你必须使用bcdedit 来禁用它,即使那样你也必须对驱动程序进行测试签名。驱动程序也不会(通常,虽然就像内核一样)创建进程,它们不是进程。
【解决方案2】:

这个问题非常不精确/模棱两可。“在 Windows 中”暗示了一些东西,但不清楚是什么。面试官可能指的是 Win32 子系统 - 即您通常作为最终用户看到的 Windows 部分。问题的最后一部分更加模棱两可。

现在,虽然进程和部分对象(在 MSDN 中称为 MMF,加载的 PE 图像,例如 .exe.dll.sys确实是内核对象 并且需要底层执行程序(和内存管理器等)的一些帮助,DLL 中的相应代码(包括 DllMain 中的代码)的行为将与任何其他用户模式进程完全相同,当从用户模式进程。也就是说,从 DLL 运行代码的每个线程最终都会转换到内核模式以使用 OS 服务(打开文件、加载 PE 文件、创建事件等),或者在足够的情况下在用户模式下做一些事情。

也许面试官甚至对有时被称为“内核空间”和“用户空间”的内存范围感兴趣,传统上是 32 位的 2 GB 边界。是的,DLL 通常在 2 GB 边界以下结束,即在“用户空间”中,而其他共享内存(内存映射文件,MMF)通常在该边界之上结束。

面试官甚至有可能成为对 DLL 的常见误解的受害者。 DLL 本身只是一块休眠的内存,它自己永远 不运行任何东西(是的,DllMain 也是如此)。当然,加载器会处理各种事情,例如重定位,但最终如果不显式或隐式调用(在加载 DLL 的进程的某个线程的上下文中),什么都不会运行。因此,出于所有实际目的,该问题需要您回问。

  • 定义“在 Windows 中”。
  • 还有“在内核模式或用户模式下加载的 dll”,这是指执行加载的代码还是最终结果(即代码运行的位置或加载的内存范围)?部分代码在用户模式下运行,其他代码在内核模式下运行。

我想知道面试官是否对他/她所问的概念有一个清晰的概念。


让我添加更多信息。从另一个答案的 cmets 看来,人们对 DLL 也存在关于驱动程序的相同误解。与 EXE(或最终的“进程”)相比,驱动程序更接近 DLL 的概念。问题是驱动程序大部分时间 自己不做任何事情(尽管它可以创建系统线程来改变它)。 驱动程序不是进程,它们不会创建进程。

【讨论】:

  • 不,另一个问题的 cmets 指的是用户模式驱动程序框架,它改变了您认为适用于驱动程序的所有规则。
  • @BenVoigt:我很困惑,尽管它们仍然不是独立的进程。我错过了什么?是否有多个 UMDF 模型?我认为它们基本上是 DLL,就像内核模式驱动程序也大致是 DLL。
  • UMDF“驱动程序”是一个可加载库,但它会加载到自己的主机进程中。它不在调用应用程序的进程内运行。
  • 啊,很公平。正如我所说,在 Windows 驱动程序方面,我更像是一个 KM 专家。
  • 我完全同意这个问题是模棱两可的,但我担心面试官只是拿着论文并相应地提出问题——他无法解释他到底想问什么......不仅仅是为了这个问题:(
【解决方案3】:

对于任何为 Windows 进行任何重要应用程序开发的人来说,答案显然是用户模式。让我解释两件事。

DLL

动态链接库与常规的旧链接库或 .lib 非常相似。当您的应用程序使用 .lib 时,它会在编译后粘贴到函数定义中。您通常使用 .lib 来存储 API 并修改函数而不必重建整个项目,只需将具有相同名称的新 .lib 粘贴到旧的并且只要接口(函数名称和参数)没有更改它仍然有效。伟大的模块化。

.dll 的作用完全相同,但它不需要重新链接或任何编译。您可以将 .dll 视为本质上的 .lib,它与使用它的应用程序一样被编译为 .exe。只需放置共享名称和函数签名的新 .dll 即可。您只需更换 .dll 即可更新您的应用程序。这就是为什么大多数 Windows 软件由 .dll 和一些 exe 组成的原因。

.dll 的使用有两种方式

隐式链接

如果您有一个 .dll userapplication.dll 以这种方式链接,您将有一个 userapplication.lib,它定义了 dll 中的所有入口点。您只需链接到静态链接库,然后将 .dll 包含在工作目录中。

显式链接

或者,您可以通过首先调用 LoadLibrary(userapplication.dll) 以编程方式加载 .dll,这将返回您的 .dll 句柄。然后GetProcAddress(handle, "FunctionInUserApplicationDll") 返回一个你可以使用的函数指针。这样,您的应用程序可以在尝试使用之前检查内容。 c# 有点不同但更容易。

用户/内核模式

Windows 有两种主要的执行模式。用户模式和内核模式(内核进一步分为系统和会话)。对于用户模式,物理内存地址是不透明的。用户模式使用映射到真实内存空间的虚拟内存。巧合的是,用户模式驱动程序也是 .dll 的。用户模式应用程序通常可以获得大约 4Gb 的虚拟寻址空间来使用。两个不同的应用程序无法有意义地使用这些地址,因为它们位于该应用程序或进程的上下文中。用户模式应用程序无法在不回退到内核模式驱动程序的情况下知道它的物理内存地址。基本上所有你习惯编程的东西(除非你开发驱动程序)。

内核模式受到用户模式应用程序的保护。大多数硬件驱动程序在内核模式的上下文中工作,通常所有的 Windows api 都分为两类用户和内核。内核模式驱动程序使用内核模式 api,不使用用户模式 ​​api,因此不使用 .dll(您甚至不能打印到控制台,因为这是用户模式 ​​api 集)。相反,他们使用 .sys 文件,这些文件是驱动程序,并且在用户模式下基本上以完全相同的方式工作。 .sys 是一种 pe 格式,所以基本上 .exe 就像 .dll 一样,就像没有 main() 入口点的 .exe。

所以从提问者的角度来看,你有两个群体

[kernel/.sys] 和 [user/.dll 或 .exe]

内核中确实没有 .exe,因为操作系统所做的一切都不是用户。当系统或其他内核组件启动时,它们通过调用 DriverEntry() 方法来完成,所以我猜这就像 main()。

所以这个问题在这个意义上是很简单的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 2012-08-26
    • 1970-01-01
    • 2020-10-15
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多