概述
Windows提供的机制有:
陷阱分发,包括中断、延迟过程调用、异步过程调用、异常分发,以及系统服务分发;
执行体对象管理器;
同步,包括自旋锁、内核分发器对象,以及等待是如何实现的;
系统辅助线程;
其他的机制,如Windows全局标志;
本地过程调用;
内核事件追踪;
Wow64。
dt nt!_ktrap_frame查看陷阱帧(trap frame)定义。
中断分发表IDT(interrupt dispatch table),每个处理器都有单独的IDT。
中断请求级别(IRQL,interrupt request level),x86中从0至31,x64中从0至15,数值越大优先级越高。前三个为软中断,分别为0(被动)、1(APC)、2(DPC/Dispatch)。高优先级可以打断低优先级中断。
HAL中会将硬件的中断请求(IRQ)映射成对应的中断请求级别(IRQL)。
中断对象可以注册一个ISR(中断外部例程)与相应的IDT项关联起来,而不必直接处理相关IDT细节,从而创建可移植的设备驱动程序。同一个IDT项可以连接多个ISR,即多个设备共享中断线。
当处理器的IRQL从DPC/Dispatch或更高级别的IRQL降低到低于DPC/Dispatch时,内核先会依次处理DPC队列中每个DPC对象的处理函数(IRQL仍然在DPC/Dispatch上),直到队列为空才下降IRQL。
DPC主要用于设备驱动,但内核也使用,内核使用DPC的一个例子是硬件时钟中断处理中,会对系统时间更新以及将当前线程计数器递减,当计数器减为0时说明该线程时限到期,内核需要重新调度,于是插入DPC介时激发线程调度。
APC队列是与特定线程相关的(DPC队列是系统范围的全局的),每个线程有它自己的队列。APC分内核模式和用户模式,内核模式无须目标线程允许就可以中断该线程并执行一个过程。一个线程IRQL提升到APC_LEVEL或调用KeEnterGuardedRegion来禁止内核APC,调用KeEnterCriticalRegion来禁止用户APC。用户APC线程运行在被动级别上,并且只有当该线程处于可警告的等待状态时(alertable wait state),APC例程才会执行,调用WaitForMultipleObjectsEx或SleepEx函数可进入警告等待。
IDT中的异常中断号:
0 除法错误
1 调试陷阱
2 NMT/NPX错误
3 断点
4 溢出
5 BOUND/打印屏幕
6 无效操作码
7 NPX不可用
8 双重异常(Double Exception)
9 NPX段溢出
A 无效任务状态段(TSS)
B 段不存在
C 栈错误
D 一般保护
E 页面错误
F Intel保留
10 符点
11 对齐检查
异常发生在用户模式下时,异常分发器首先查看引发该异常的进程是否有一个相关联的调试端口,有则向调试端口对象发送第一次机会的调试消息。
如果调试器不处理异常或没有调试器,异常分发器切换到用户模式,将陷阱帧按照CONTEXT格式拷贝到用户栈,查找基于帧的异常处理器,没有找到或找到不处理,异常分发器切换回内核模式,第二次调用调器试。如果第二次还不处理的话,内核最后向该进程关联的异常端口发送消息,此异常端口一定是由环境子系统注册的,典型的处理就是弹消息框后终止进程。
线程内部启动函数一般都包含了一层异常处理,最终的默认处理为未处理异常过滤器(UnhandledExceptionFilter)。HKLMSOFTWAREMicrosoftWindows NTCurrentVersionAeDebug下的Auto和Debugger,Auto值告诉异常过滤器是否自动运行调试器,Debugger为调试器路径。
32位系统服务分发:
P2之前处理器上,Windows使用int 2e自陷指令进入IDT表46号项下的系统服务分发器,eax中存放着系统服务号,ebx指向参数列表。
P2及以上的处理器,Windows使用专门的sysenter指令,为支持这一指令,Windows在引导时将内核的系统服务分发器地址保存在与之相关联的寄存器中,eax中存放着系统服务号,edx指向参数列表。系统分发器通常执行sysexit指令返回(除非单步调试时使用iretd返回)。
64位系统服务分发:
Windows使用syscall指令进行系统服务分发(AMD可以的啊,这回牛了),系统调用号通过eax来传递,前4个参数存放在寄存器中,其他参数存放在栈中。
系统服务分发器KiSystemService会将参数从用户栈拷贝至内核栈。Widnows有两个内置的系统服务表,32位的系统服务号其中一个2位域解释成一个表索引,低12位为表中的索引。
每个对象都有一个对象头和一个对象体,对象头中有指向进程列表的指针,列表中每个进程都打开了此对象,同时对象头中也有指向类型对象(type object)的指针。dt _object_header 地址,查看对象头信息;dt _object_type 地址,查看类型对象信息。
在创建一个新的对象类型时,可以向对象管理器注册调用方法,使得对象管理器可以在某些明确点上调用这些方法,比如对象创建、删除时。
对象句柄是一个索引,进程块(EPROCESS)中有一个域指向进程的句柄表,第一个句柄索引是4,第二个8,依次类推。这是一个三层结构的索引表,句柄值低24位每8位分别是这三个句柄表的索引。每个句柄项包含一个对象指针以及一个32位的访问掩码。
内核中有一张内核句柄表(ObpKernelHandleTable),在内核句柄表中创建的句柄只能在内核模式下才能访问,但不限于任何进程环境。对象管理器把大于0x80000000句柄值看做内核句柄表中的句柄。
对象保持力:应用程序打开一个对象时,该对象的头信息句柄计数和引用计数加1,关闭的时候减1,当句柄计数为0时对象管理器从全局名字空间中删除该对象的名字,删除后可避免新的进程再打开该对象句柄。而内核在访问对象时通常使用指针,所以对象管理器只对引用计数加减,当引用计数为0时,删除该对象。(分开两个计数设计的秒啊)
高IRQL的同步:
单处理器的同步方法,内核在使用一个全局资源前,临时屏蔽那些在中断处理例程也用到该资源的中断,做法是将处理器IRQL提升到访问该全局资源的用到的最高IRQL级别。
使用依赖硬件多处理安全操作指令安全操作整数,如InterlockedIncrement、InterlockedDecrement、InterlockedExchange、
InterlockedCompareExchange等函数,是利用x86的lock指令前缀锁住多个处理器总线。
多处理器中,内核使用自旋锁(spinlock)机制同步,自旋锁是一个与某个全局数据结构相关的锁原语。自旋锁驻留在全局内存中,获取自旋锁是使用硬件支持的test-and-set操作实现的。
在Windows中自旋锁有一个之关联的IRQL,并且总是在DPC/Dispatch级别或以上,处理器在获得自旋锁的时候,等于或低于此IRQL的其他活动都要停止下来,如线程分发活动(工作在DPC/Dispatch上),获得自旋锁的线程不会被抢占直到释放了自旋锁。内核函数KeAcquireSpinlock和KeReleaseSpinlock用来操作自旋锁。使用自旋锁要小心,正如前面所说的原因,获得自旋锁后不能企图上调度器执行一个分发操作,或引发缺页异常,都会导致系统崩溃,因为它无法被切换抢占。关于自旋锁还有一种非标准的排队自旋锁(queued spinlock)。
低IRQL的同步:
Windows进程通常使用临界区函数EnterCriticalSection和LeaveCriticalSection同步资源,使用此函数比使用互斥体的好处是,在没有竞争的情况下不会进入内核等待,在竞争时,EnterCriticalSection会动态分配一个事件对象并等待信号。
nt!_dispatcher_header对象的分发器头,nt!_kwait_block等待块,内核在设置对象信号后,从对象分发器头WaitListHead链表搜索每一个等待块,一个等待块代表一个等待的线程,等待块中的Thread指向_KTHREAD结构地址,如果此线程满足要求(没有等待其他对象),把线程状态从等待改变成就绪并加入调度器的就绪队列。
系统辅助线程,ExQueueWorkItem或IoQueueWorkItem,可以请求一个辅助线程服务。
Windows全局标志:全局标志保存在NtGlobalFlag的全局变量中,系统引导是根据注册表HKMLSYSTEMCurrentControlSetControlSession Manager下GlobalFlag值来初始化,默认值为0,全局标志可以打开操作系统内部的调试、跟踪和验证支持。
本地过程调用(LPC):用户模式下,两个进程间的通讯机制,内核模式的组件也可以使用LPC与用户进程通信。
Wow64指64位Windows上的Win32仿真,以一组用户模式DLL的形式来实现,包括:
Wow64.dll 管理进程线程创建、异常分发、Ntoskrnl.exe导出的基本系统调用、文件系统重定向、注册表重定向和反射;
Wow64Cpu.dll 为所有在Wow64内部运行的线程,管理32位CPU环境,即CPU从32位到64位或从64位到32位的模式切换,提供与体系结构相关的支持;
Wow64Win.dll 截取Win32k.sys导出的GUI系统调用。
一个32位的程序调用32位的Ntdll.dll,Ntdll.dll下由Wow64Cpu.dll支持,Wow64Cpu.dll分别由Wow64.dll与Wow64Win.dll,这两个DLL又调用64位的Ntdll.dll最终调用内核服务。
最后
以上就是优雅秀发为你收集整理的深入解析Windows操作系统(笔记3)的全部内容,希望文章能够帮你解决深入解析Windows操作系统(笔记3)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复