Posted on 2009-10-25 00:24
S.l.e!ep.¢% 阅读(1546)
评论(1) 编辑 收藏 引用 所属分类:
RootKit
2.1.3 无处不在的内核模块
http://book.51cto.com 2009-05-26 22:56 谭文/杨潇/邵坚磊 电子工业出版社 我要评论(0)
摘要:《寒江独钓:Windows内核安全编程》第2章内核编程环境及其特殊性,本章首先介绍内核程序的生存运行环境,然后介绍在Windows内核编程中,所习惯遵守的“WDK编码习惯”,主要是其中所用的新定义的数据类型,以及在内核编程中所常用的一些函数调用等。本节为大家介绍无处不在的内核模块。
标签:Windows 内核编程 寒江独钓:Windows内核安全编程
2.1.3 无处不在的内核模块
位于高2G空间内的操作系统内核,并非做死的一个巨大程序。因为计算机硬件种类繁多,不可能做出一个能支持所有硬件的巨大内核。
内核是有接口的,微软提供规定的格式,让硬件驱动的编程人员,能按照规定的格式编写“驱动程序”。这些驱动程序能够作为模块加载到内核中,成为内核的一部分,这样内核只要简单地安装驱动程序,就可以适应各种不同的硬件了。
本书中的大部分例子都是编译成内核模块的,实际上也可以称为驱动程序(Driver)。但是它们大部分并不驱动任何硬件,有人称之为“软件驱动”。但是笔者认为这不够贴切,所以本书使用Linux程序员们的叫法,称之为内核模块(Kernel module)。也许这样要更贴切一些,驱动程序可以看成内核模块的一种(少量的应用层驱动程序除外)。
内核模块已经位于内核空间,作为R0代码执行,所以不受任何限制,可以任意修改内核。因此许多使用应用程序无法实现的功能,可以通过编写内核模块来实现。
起初的Windows,似乎并没有打算让应用软件的编程人员来提供内核模块。但是,一些特殊的应用软件的编程人员首先自己突破了这些限制,他们编写了虚拟光驱、防毒软件的实时监控、防火墙等特殊的不驱动任何硬件的内核模块。最终微软也意识到了内核编程对软件也是很有用的,因此在内核中又提供了更多的接口,比如方便进行文件过滤、网络过滤等的新接口,这些是专门提供给非硬件驱动开发的软件编程人员使用的。
WDK是微软目前提供的最新的驱动开发包,同时也包括了给软件内核编程提供的所有接口和例子。硬件驱动与软件的内核编程这二者目前并没有严格分开,双方的技术和许多代码都是相通的。
初学者在编写一个内核模块时,常常有的一个疑问就是:这些代码运行在哪个进程的空间中呢?
内核模块位于内核空间,而内核空间又被所有的进程共享。因此,内核模块实际上位于任何一个进程空间中。但是任意一段代码的任意一次执行,一定是位于某个进程空间中的。这个进程是哪一个?这取决于请求的来源、处理的过程等。PsGetCurrentProcessId函数能得到当前进程的进程号,这个函数的原型如下:
HANDLE PsGetCurrentProcessId();
这个函数返回的HANDLE,实际上是一个进程ID。这个数字和我们打开任务管理器时,看到的PID是一样的。
有些读者会误以为所有内核代码都运行在系统进程内。
Windows的所谓系统进程是一个名为“System”的进程,是Windows自身生成的一个特殊进程,这个进程在Windows XP下PID始终为4。读者只要调用PsGetCurrentProcessId就会发现内核模块中分发函数调用时,当前进程一般都不是System进程。但是DriverEntry函数被调用时,一般都位于系统进程中。这是因为Windows一般都用系统进程来加载内核模块,并不说明内核代码始终运行在System进程里。