|
Windows服务调用机制(2) 应用程序编程接口 基于NTDLL.dll的本地系统服务 (用户模式) ----------------------------------------- 系统服务调用 (内核模式) 执行体 系统内核,设备驱动程序 硬件抽象层
三、Windows 2000本机系统服务(Native API)
Windows 2000本机系统服务又称为Windows本机应用程序编程接口,它是由执行体(Executive)为用户模式和内核模式的程序提供的系统服务集。它包含两种类型的函数:Windows 执行系统服务的系统服务调度占位程序;子系统,子系统DLL和其他本机映像使用的内部支持函数。
从用户模式调用本机系统服务是通过NTDLL.dll来实现的。表面上,Win32函数为编程人员提供了很多接口来实现我们想要的功能,但是这些Win32函数只不过是本机应用程序编程接口的一个包装器而已,它们将本机API包装起来,调用本机系统服务来实现用户期望的功能。也就是说NTDLL.dll只是系统服务调用接口在用户模式下的一个外壳。关于用户模式下的Windows本机系统服务的相关信息,请参见我以前写的一篇文章《探测Windows2K/XP/2003本机系统信息》。
我们再谈谈从内核模式调用系统服务吧,这时就不是由NTDLL.dll导出系统服务调用的函数接口了,而是由ntoskrnl.exe来实现的,它会提供两种形式的函数:ZwXxx和NtXxx,在此我们就不多说了。大家应该注意到了,在上面我们介绍的Windows 2000系统体系结构中的系统服务调用,执行体和内核都是存在于ntoskrnl.exe(在多处理器中为ntkrnlmp.exe)之中,并且是分层的。
四、Windows 2000系统服务调用机制
Windows 2000的陷阱调度(Trap Dispatching)机制包括了:中断(Interrupt),延迟过程调用(Deferred Procedure Call),异步过程调用(Asynchronous Procedure Call),异常调度(Exception Dispatching)和系统服务调用。在Intel x86的Windows 2000系统中,处理器执行int 0x2e指令来激活Windows系统服务调用;在Intel x86的Windows XP系统中处理器却是通过执行sysenter指令使系统陷入系统服务调用程序中;而在AMD的Windows XP中使用了指令syscall来实现同样的功能。我们暂时使用x86的Windows 2000为例来演示。我们先给出一个系统服务调用的模型:
mov eax, ServiceId lea edx, ParameterTable int 2eh ret ParamTableBytes
其中,ServiceId清楚的说明了传递给系统服务调用的系统服务号,内核使用这个标识符来查找系统服务调度表(System Service Dispath Table)中的对应系统服务信息。在系统服务调度表中的每一项包含了一个指向系统服务程序的指针,我们Hook时就是修改这个指针使其指向我们自定义的系统服务的地址。ParameterTable是传递的参数,系统服务调用程序KiSystemService必须严格校验传递的每一个参数,并将其参数从线程的用户堆栈中复制到系统的核心堆栈以备使用。由于执行int指令会导致陷阱发生,所以在Windows 2000内的中断描述表(IDT = Interrupt Descriptor Table)中的0x2e项指向了系统服务调用程序。最后返回的ParamTableBytes是关于参数个数的信息。
现在我们已经看得出来了,系统服务调用只是一个接口,它提供了将用户模式下的请求转发到Windows 2000内核的功能,并引发处理器模式的切换。在用户看来,系统服务调用接口就是Windows内核组件功能实现对外的一个界面。系统服务调用接口定义了Windows内核提供的大量服务。
|