Windows一般都用系统进程来加载内核模块
2009-06-05 13:50
453 查看
无处不在的内核模块
本文节选自《寒江独钓》一书
位于高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进程里。
本文节选自《寒江独钓》一书
位于高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进程里。
相关文章推荐
- 加载内核模块,实现新的系统调用:遍历系统当前所有进程的任务描述符,并将pid组织成树状结构显示
- 发生系统错误 1275.此驱动程序被阻止加载 寒江孤钓<<windows 内核安全编程>> 学习笔记
- 设计一个模块,功能是列出系统中所有内核线程的程序名、PID号和进程状态。
- Windows系统的四个重要概念——进程、线程、虚拟内存、内核模式和用户模式
- 【内核】Linux添加系统调用(静态,非动态加载模块)
- 遍历Windows系统的内核模块(源码)
- linux ps 命令的结果中VSZ,RSS,STAT的含义和大小 发表于2013 年 6 月 17 日 ps是linux系统的进程管理工具,相当于windows中的资源管理器的一部分功能。 一般来
- Linux如何在系统启动时自动加载内核模块
- 在Ubuntu上为Android系统编写Linux内核驱动程序 + 编写加载动态模块ko
- 枚举当前系统进程以及进程加载模块
- 基于visual c++之windows核心编程代码分析(19)枚举进程以及进程加载模块信息
- Linux如何在系统启动时自动加载内核模块
- 编译时向内核添加新设备 模块的方式动态的将驱动加入内核,但这种方式加入的驱动程序,当系统重新启动时, 还需要重新用模块的方式进行插入,如果是系统内常用的设备驱动采用这种方式进行加载, 就会很不方便。
- Linux如何在系统启动时自动加载内核模块
- 遍历Windows系统的内核模块
- Linux如何在系统启动时自动加载内核模块
- apicloud git-svn 地址冲突,导致代码管理功能不可用.这个问题是由 windows 系统自身DLL加载机制引起的.一般重启电脑即可解决
- x64windows安全机制进程_线程_模块加载回调摘要
- Linux如何在系统启动时自动加载内核模块
- Linux如何在系统启动时自动加载内核模块