tel*_*all 8 windows operating-system kernel interrupt dispatcher
我在内核和用户模式中有一些与Windows进程相关的问题.
如果我有一个hello world应用程序,以及一个公开新系统调用的hello world驱动程序foo(),我很好奇我在内核模式下能做什么,不能做什么.
对于初学者来说,当我编写新的hello world应用程序时,我会获得一个新进程,这意味着我拥有自己的用户模式VM空间(让它保持简单,32位窗口).所以我有2GB的空间,我"拥有",我可以偷看,直到我心中的内容.但是,我受到我的程序的约束.我不能(不要让共享内存进入这个)触摸任何人的记忆.
如果,我写这个hello world驱动程序,并从我的用户应用程序调用它,我(驱动程序代码)现在处于内核模式.
第一个澄清/问题:我仍处于与用户模式应用程序相同的过程中,对吗?仍然有相同的PID?
内存问题:内存作为虚拟机呈现给我的进程,即使我有1GB的内存,我仍然可以访问4GB内存(2GB用户/ 2GB内核 - 不关注服务器上的交换机细节,或者具体,只需一个这里的一般假设).作为一个用户进程,我无法窥视任何内核模式的内存地址,但我可以做任何我想要的用户空间,对吗?
如果我调用我的hello world驱动程序,从驱动程序代码中,我是否仍然拥有相同的用户模式内存视图?但是现在我还可以在内核模式下访问任何内存?
这个内核模式是内存SHARED(与用户模式不同,这是我自己的进程拷贝)?也就是说,编写驱动程序更像是为单个进程编写线程应用程序(操作系统除外?)
下一个问题.作为驱动程序,我可以更改正在运行的进程吗?说,我知道另一个应用程序(比如用户模式的web服务器),并为该进程加载VM,更改它的指令指针,堆栈,甚至将不同的代码加载到进程中,然后切换回我自己的应用程序?(我不想在这里做任何邪恶的事情,我只是好奇它在内核模式下的真正含义)?
此外,一旦进入内核模式,我可以阻止操作系统抢占我吗?我认为(在Windows中)您可以设置您的IRQL级别来执行此操作,但即使在阅读Solomons书籍(Inside Windows ...)之后,我也不完全理解这一点.我将问另一个与IRQL/DPC直接相关的问题但是,现在,我想知道内核驱动程序是否有能力将IRQL设置为High并接管系统.
更多内容,但这些问题的答案将有所帮助.
每个进程都有一个"上下文",其中包含特定于该进程的VM映射(通常在32位模式下<2 GB).当在用户模式下执行的线程进入内核模式时(例如,来自系统调用或IO请求),同一线程在此过程中仍在使用相同的上下文执行.PsGetCurrentProcessId此时将返回相同的东西,因为GetCurrentProcessID刚好在用户模式之前(与线程ID相同).
进入内核模式后,上下文附带的用户内存映射仍然存在:您可以直接从内核模式访问用户内存.有迹象表明,需要做的这是安全的,虽然特殊的东西:既不使用也不缓冲直接I/O.特别是,用户空间范围内的无效地址访问尝试将引发需要捕获的SEH异常,并且由于该进程中另一个线程的操作,用户内存的内容可能随时发生变化.访问内核地址范围中的无效地址会导致错误检查.在用户模式下执行的线程无法访问任何内核内存.
内核地址空间不是进程上下文的一部分,因此在所有内核之间映射相同.但是,任何时候任何数量的线程都可能在内核模式下处于活动状态,因此它不像单线程应用程序.通常,线程在进入内核模式时为自己的系统调用提供服务(而不是让专用的内核工作线程处理所有请求).
保存线程和进程状态的底层结构在内核模式下都可用.通过从该进程创建MDL并将其映射到系统地址空间,最好从另一个进程映射另一个进程的VM.如果您只想更改另一个线程的上下文,可以完全从用户模式完成.请注意,必须挂起一个线程才能在没有竞争条件的情况下更改其上下文.不建议将模块从内核模式加载到进程中; 所有加载器API仅供用户模式使用.
每个CPU都有一个正在运行的当前IRQL.它确定哪些东西可以中断CPU当前正在做什么.只有来自更高IRQL的事件才能抢占CPU的当前活动.
PASSIVE_LEVEL是所有用户代码和大多数内核代码执行的地方.许多内核API都需要IRQLPASSIVE_LEVELAPC_LEVEL 用于内核APCDISPATCH_LEVEL用于调度程序事件(在NT术语中称为调度程序).在此级别运行将阻止您被调度程序抢占.请注意,在此级别出现任何类型的页面错误是不安全的; 内存管理器尝试检索页面时会出现死锁的可能性.如果页面出现DISPATCH_LEVEL或超过页面错误,内核将立即进行错误检查.这意味着您无法安全地访问页面缓冲池,分页代码段或任何尚未锁定的用户内存(即通过MDL).DIRQL.HIGH_LEVEL.什么都不能抢占这个水平.在错误检查期间,内核使用它来暂停系统.我建议阅读Scheduling,Thread Context和IRQL
有关此主题的一个很好的入门知识可以在以下位置找到:http://www.codinghorror.com/blog/archives/001029.html
正如 Jeff 对于用户模式内存空间所指出的那样:
“在用户模式下,执行代码无法直接访问硬件或引用内存。在用户模式下运行的代码必须委托给系统 API 来访问硬件或内存。由于这种隔离提供的保护,用户模式下会崩溃总是可恢复的。在您的计算机上运行的大多数代码都将在用户模式下执行。”
因此您的应用程序将无法访问内核模式内存,事实上您与驱动程序的通信可能是通过 IOCTL(即 IRP)。
然而,内核可以访问所有内容,包括用户模式进程的映射。这是一条单行道,出于安全和稳定性原因,用户模式无法映射到内核模式。即使通过内核模式驱动程序可以映射到用户模式内存,我也不建议这样做。
至少在 WDF 之前是这样。我不确定用户模式驱动程序的内存映射功能。
| 归档时间: |
|
| 查看次数: |
3740 次 |
| 最近记录: |