我在接受采访时被问到这样一个问题:
在Windows中,假设有一个依赖于一些dll的exe,当你启动exe时,然后依赖的dll将被加载,这些dll是以内核模式还是用户模式加载的?
我不太清楚这个问题,而不是提到的答案 – 你能帮忙解释一下吗?
谢谢。
检测操作系统批次
状态读取在LWP Useragent中失败
当中断被触发时是否发生上下文切换?
我可以确定我是否在VB6的Win7操作系统?
明确捕获和处理的exception是否会切换到内核模式?
什么是可重入内核
如何“杀”工作? 特别是如何“封杀”工作被封锁的过程?
JVM内存和cpu使用的实际限制?
这个问题很不精确/不明确。 “在Windows中”提出了一些建议,但不清楚是什么。 面试官可能指的是Win32子系统 – 也就是你通常作为最终用户看到的Windows部分。 问题的最后部分更加模糊。
现在,当进程和段对象(在MSDN中称为MMF,加载的PE映像如.exe和.dll和.sys )确实是内核对象,并需要底层执行程序(和内存管理器等) 当从用户模式进程 DllMain DLL时(包括DllMain的DLL),其行为与任何其他用户模式进程完全相同。 也就是说,运行DLL代码的每个线程都将转换到内核模式,以最终使用OS服务(打开文件,加载PE文件,创建事件等),或者在用户模式下做足够的事情。
也许面试官甚至对有时被称为“内核空间”和“用户空间”的内存范围感兴趣,通常在32位的2 GB边界处。 是的,DLL通常最终在2 GB的边界以下,即在“用户空间”,而其他共享内存(内存映射文件,MMF)通常结束在该边界以上。
面试官甚至有可能成为关于DLL的常见误解的受害者。 DLL本身只是一个休眠的内存,它并没有自己运行任何东西(是的,对于DllMain也是如此)。 当然,加载器会处理所有类型的东西,比如重定位,但是最终没有任何东西会被显式地或者隐式地调用(在加载DLL的进程的某个线程的上下文中)。 所以,为了所有的实际目的,这个问题需要你回来。
定义“在Windows中”。
另外,“在内核模式或用户模式下加载的dll”,这是否指的是执行加载或最终结果的代码(即代码运行的地方或在哪个内存范围内加载)? 该代码的一部分以用户模式运行,其他以内核模式运行。
我想知道面试官是否对他/她所问的概念有清晰的认识。
让我再添加一些信息。 从另外一个答案的评论看来,人们对DLL也存在着同样的关于驱动程序的误解。 驱动程序更接近DLL的想法,而不是EXE(或最终的“过程”)。 问题在于,驱动程序大部分时间都没有做任何事情(虽然它可以创建系统线程来改变它)。 驱动程序不是进程,不会创建进程。
我不是Windows内部工作方式的专家,但是对于我所知道的正确答案是用户模式,只是因为只有与操作系统相关的进程才被允许在内核空间http://en.wikibooks.org/维基/ Windows_Programming / User_Mode_vs_coreel_Mode
对于任何为Windows进行任何重要的应用程序开发的人来说,答案都是非常明显的用户模式。 让我解释两件事。
DLL
动态链接库与常规旧链接库或.lib非常相似。 当你的应用程序使用.lib时,它会在编译时间之后粘贴到函数定义中。 您通常使用.lib来存储API并修改这些函数,而不必重新构建整个项目,只需将新的.lib与旧的相同名称粘贴起来,只要界面(函数名称和参数)没有改变它仍然有效。 伟大的模块化。
.dll做完全相同的事情,但它不需要重新链接或任何编译。 你可以把.dll当成一个.lib,它被编译成一个.exe,就像使用它的应用程序一样。 简单地把共享名称和功能签名的新.dll,它只是工作。 您可以简单地通过替换.dlls来更新您的应用程序。 这就是为什么大多数Windows软件包含.dll和一些exe文件。
使用.dll有两种方法
隐式链接
如果你有一个.dll userapplication.dll你可以使用userapplication.lib来定义dll中的所有入口点。 您只需链接到静态链接库,然后将.dll包含在工作目录中。
显式链接
事实上,您可以通过首先调用LoadLibrary(userapplication.dll)以编程方式加载.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()。
所以这个问题在这个意义上是相当简单的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。