再“弹”谈WindwsNT内核下文件系统过滤驱动程序开发

山东蓝鸟贵薪 2011-07-29 10:25:15
加精
再“弹”谈WindwsNT内核下文件系统过滤驱动程序开发
WindOwsNT 和基于NT内核的WindOws2000/XP操作系统中,通常需要通过开发文件系统过滤驱动程序来保证文件系统的信息安全运行,主要包括动态病毒扫描、透明文件加密解密、文件保护和系统恢复等功能。文件系统驱动程序(FileSystemDriver,简称FSD)管理文件系统格式。WindOwSNT的文件系统驱动程序是I/O子系统的一个组件,为用户提供在磁盘或者磁带等非易失性存储介质上存取数据服务。WindOwsNT的文件系统驱动程序和其他的设备驱动程序的一个主要的区别就在于文件系统驱动程序和内存管理器、高速缓存管理器有机的结合在一起,有着密不可分的关系。为了提高系统性能,FSD通常使用高速缓存(Cache)管理器以高速缓存文件数据。FSD还和内存管理器结合起来,以使内存映射文件能被正确实现_1J。本文首先探讨文件系统过滤驱动程序开发的原理和步骤,然后给出一个实现文件透明加密解密的实例。由于Wind0wSNT/20O0/XP操作系统的文件系统过滤驱动程序开发有着很类似的方面,下文中如果没有特别说明,则是针对以NT内核为基础的WindOwsNT/2000操作系统而言的。

1 文件系统过滤驱动程序开发

WindOwsNT 的I/O管理器是一个可扩展的结构,通过开发过滤驱动程序可以扩展I/O子系统的功能。I/O管理器支持分层驱动程序模型,每个I/O请求包(IRP)的处理分别经过各层驱动程序,直到某层驱动程序完成这个请求。这样第三方开发的驱动程序就有机会插入到这个层次结构中并获得截获及处理来自上层的操作请求的机会,把这种驱动程序称为过滤驱动程序。

文件系统过滤驱动程序是针对文件系统而言的。WindOwsNT的I/O管理器根据用户的文件操作请求构造IRP发到文件系统驱动程序,文件系统驱动程序把相应于文件系统的操作转换为相应于存储设备驱动程序的操作并通过I/O管理器来调用存储设备驱动程序。I/O管理器在发送操作请求到目标设备之前会检查是否有其他的设备附着于目标设备对象之上。通过构造附加的设备对象附着在文件系统或者存储设备对象之上,并为该设备对象指定专门的驱动程序,I/O管理器就会把要发送到目标设备的请求先发到附加的过滤设备,在该设备对应的过滤驱动程序中对原始请求加入附加的处理来实现对文件系统操作的截取、监控甚至替换。

文件系统过滤驱动程序可以附着在文件系统驱动程序之上,也可以加入到文件系统驱动程序和存储设备驱动程序之间,如图1所示。具体实现一个过滤驱动程序的基本步骤包括:构造一个设备对象(过滤设备)附着在目标设备上;在这个过滤设备对应的驱动程序(过滤驱动程序)中截取发送到目标设备的操作;在过滤操作中可能需要构造新的IRP来驱动下层驱动程序,也可能需要为某个IRP指定对应的完成例程以便这个IRP被下层驱动程序完成返回后调用;在合适的时候可以断开过滤程序。

图 1 文件系统过滤驱动程序在系统中的位置



2 文件透明加密解密的过滤器实例

下面给出一个在WindOwT下进行文件加密解密的过滤器具体实现过程。用户的数据在存储到磁盘上设定的安全区域(例如安全文件夹)之前经过了加密处理,读取时经过解密返回给用户,这个过程对用户来说是透明的。对这个安全区域访问时先要通过认证处理,这样就保证了安全区域里的数据安全。对于现有的WindOwsNT/2000/XP系列操作系统的文件系统本身来说,只是对WindOws2000/XP支持的5。0版本以上的NTFS文件系统本身实现了加密文件系统(EFS)。对所有文件系统分区的文件实现透明的加密解密并采用特殊的加密算法,就需要通过文件系统过滤驱动程序来实现。

在文件系统驱动程序和硬盘驱动程序之间加入过滤驱动程序。当文件系统驱动程序写硬盘的时候,过滤驱动程序首先对数据进行加密然后再调用硬盘驱动程序。当文件系统驱动程序读硬盘的时候,过滤驱动程序先调用硬盘驱动程序读取数据并对从硬盘返回的已加密数据进行解密,然后再返回给文件系统驱动程序。过滤器在系统中位于文件系统驱动程序和磁盘驱动程序之间。

要实现这个过滤器,首先需要把过滤器挂接在某个硬盘分区之上,可以在过滤驱动程序的DriverEntry例程或者应用程序中调用DeviceIO—COntrOl发送一个IOC~L请求驱动程序来挂接到硬盘上。该过程的函数调用过程为:由ZwCreate—File得到硬盘分区的设备句柄,再用ObRefer—enceObjectByHandle得到对应的FILE—OBJECT指针(wind0wsNT把每个设备当作一个文件来看待,并有一个对应的FILE—OBJECT结构描述其属性),调用IOGetRelatedDevieeObjeet得到硬盘分区设备对象指针。然后调用IOCreateDevice来构造代表过滤器的一个设备并为它指定驱动程序也就是过滤驱动程序。最后调用IOAttachDe—viceByPOinter把该设备挂接在硬盘分区设备上。这样文件系统驱动程序发送到这个硬盘分区设备的所有请求都会先经过过滤器。

硬盘驱动程序由DriverEntry提供一系列的IRP处理函数供高层驱动程序调用。在过滤驱动程序中实现加密解密是通过截取IRP_MJ_READ和IRP_MJ_WRITE来实现的。在过滤驱动程序的DriverEntry例程中指定处理函数:DriverObject->MajOrFunctiOn[IRP_MJ_WRITE] = MyFilterWrite;DriverObject->MajOrFunctiOn[IRP—MJ—READ] = MyFilterRead。

在IRP—MJ—WRITE的处理函数中如果需要加密处理就在非分页内存中分配一段与待写数据空间大小相同的内存,并把待写数据拷贝到这段内存中,对这段内存数据调用加密处理,建立这段内存的内存描述符MDL,更新IRP结构中的Irp->MdlAddress指向这个新建立的MDL,并记住原先的值。为这个IPR指定一个完成例程,接着调用下层的硬盘驱动程序写入已加密数据。硬盘驱动程序完成这个写操作并返回后,系统会调用指定的这个完成例程。在完成例程中恢复Irp->MdlAddress为原来的值并且释放原先分配的那段内存。

在IRP—MJ—READ的处理函数中解密是一个近似相反的过程。先直接调用硬盘驱动程序取得数据,然后在它的完成例程中对读取的数据进行解密返回上层驱动程序。

3 主要应用和展望

基于文件系统过滤驱动程序可以实现动态的病毒扫描。文件系统针对病毒的安全措施有两种:一种是以杀为主的静态反病毒措施,另一种是以防为主的动态反病毒措施。动态的反病毒措施也就是对病毒实时监控,这个可以通过文件系统过滤驱动程序来实现。基本方法是在文件系统驱动程序上面加入一个过滤驱动程序来过滤被病毒感染的文件。这个过滤驱动程序先于文件系统看到I/O操作请求,在截取到上层传下来的写操作请求时如果侦测到病毒特征就拒绝这个请求,保证硬盘数据的安全。

另外,利用文件系统过滤驱动程序可以实现分级的存储管理。举例来说,一个系统中有两个存储设备,一个存取速度很快价格很昂贵;另一个存取速度较慢但是价格便宜。可以作一个过滤驱动程序附着在文件系统驱动程序之上来优化系统性能。把不常用的数据放在慢速设备上,当截取到对这些数据的操作请求时先把这些数据转移到快速设备然后再向下传递原来的操作请求到文件系统驱动程序,这样就可以在现有设备不变的情况下获得更好的系统性能。

开发文件系统过滤驱动程序的用途在于它可以扩展、修改、甚至替代现有文件系统的操作而不用重新开发新的文件系统驱动程序。随着信息技术的发展和WindOwsNT应用的普及,文件系统过滤驱动程序的开发会有着更广泛的应用
...全文
4149 115 打赏 收藏 转发到动态 举报
写回复
用AI写文章
115 条回复
切换为时间正序
请发表友善的回复…
发表回复
山东蓝鸟贵薪 2011-10-08
  • 打赏
  • 举报
回复
继续学习内核编程中
stonemqy 2011-10-08
  • 打赏
  • 举报
回复
学习了。收藏了。
山东蓝鸟贵薪 2011-10-05
  • 打赏
  • 举报
回复
太受伤了呀
高手们............
雁过留毛 2011-10-04
  • 打赏
  • 举报
回复
顶一下...
山东蓝鸟贵薪 2011-10-04
  • 打赏
  • 举报
回复
不会研究
内核的高手怎么没有出手呀
山东蓝鸟贵薪 2011-09-21
  • 打赏
  • 举报
回复
继续努力学习中..........
  • 打赏
  • 举报
回复
标志一下
山东蓝鸟贵薪 2011-09-09
  • 打赏
  • 举报
回复
还请
各位高手
多多赐教呀
akuo 2011-09-09
  • 打赏
  • 举报
回复
学习, 收藏
lyhoo163 2011-09-08
  • 打赏
  • 举报
回复
关注。
山东蓝鸟贵薪 2011-09-08
  • 打赏
  • 举报
回复
请各路高手们顶顶我的帖子呀,
也请多多赐教

山东蓝鸟贵薪 2011-09-08
  • 打赏
  • 举报
回复
高手们顶顶帖子,这么好的“课题”,顶顶呀
山东蓝鸟贵薪 2011-09-07
  • 打赏
  • 举报
回复
不会,高手们顶顶呀...................
山东蓝鸟贵薪 2011-08-11
  • 打赏
  • 举报
回复
不会,没有高手举个实例程序呀???????????
山东蓝鸟贵薪 2011-08-05
  • 打赏
  • 举报
回复
继续学习中.......
山东蓝鸟贵薪 2011-08-04
  • 打赏
  • 举报
回复
Windows启动过程预览
1. MBR & Boot Sector

物理硬盘是以扇区(sector)为单位来寻址的。Windows的安装程序会在安装的时候,将一些内容写入你

安装系统的那个硬盘的第一个扇区。这块内容就称为Master Boot Record(MBR).

MBR包括两块内容:
(1). Boot code;
(2). Partition table;

Boot code,也就是启动代码。这段代码是在系统启动的时候,BIOS完成了自检过程,选择了启动设备(

也就是你某个硬盘),然后就将该磁盘的MBR读入内存,并且跳转到MBR所在地址,从而执行其Boot code.

Partition table,也就是分区表。该表只有4项(entry),因为MS的OS允许一个磁盘最多被分为4个主分

区(primary partition)。这里的分区表里面的内容就是这4个分区的相关信息,包括其起始的sector,

相应的标志等等。

对于启动过程而言,MBR的boot code会搜寻这个分区表,在其中查找带有可启动标志(也称为Active)的

分区,然后将该分区的第一个sector(也就是Boot sector)读入,并且执行其中的代码。

在安装程序写入Boot sector之前,需要获知其所在分区的文件系统类型(FAT? FAT32? NTFS?),然后写

入不同的Boot sector。为什么对于不同的文件系统需要不同的Boot sector呢?原因在于Boot sector的

任务,就是要载入OS的系统启动文件,而载入文件的过程,是需要文件系统参与的,所以对应于不同的文

件系统,在Boot sector里面就需要不同的文件系统支持代码,以次来完成系统文件的加载。对于Windows

启动而言,需要加载的文件为Ntldr。

需要补充的是,boot sector里面对于文件系统的支持代码是“最小化”了的。毕竟boot sector的大小最多

也就只有512 bytes,要带有完整的文件系统是不大可能的。而且,我们的需求也很简单,只需要它能够

理解该文件系统,并且能够读取其中的文件就可以了,我们并没有写入文件的需求。

Boot sector将Ntldr加载完成之后,就跳转到Ntldr的入口处,接下去的任务,就交给Ntldr了。这时候,

系统还是运行在16位的实模式下,Ntldr会开启Paging,并转入32为保护模式。

这个过程中,可能碰到的错误信息是下面这个:
对于NTFS文件系统,"BOOT: Couldn't find NTLDRP";
对于FAT文件系统,"NTLDR is missing";
这个错误的意思是Boot sector在分区的根目录下没有找到Ntldr。

2. NTLDR

NTLDR是一个“中间人”,在Boot Sector转入NTLDR的时候,系统处于实模式下,这时候程序访问的任何地址都是实地址,也就是物理地址(虽然这其中还有80x86最基本的分段功能,学过这个实模式汇编的应该知道),并且,这个地址范围也受限在1M(20位地址)以内。所以,进入NTLDR后最先要做的事情就是转入保护模式,以便于能够完全访问32位地址范围。不过,由于此时没有设置好相应的页表,所以,还不能进行虚实地址转换(也就是还没有分页的功能)。

NTLDR需要初始化一定的页表,然后开启分页。这时候,系统已经进入了Windows的标准状态(保护模式+分页)。前面说到转入保护模式的时候,漏说了一个事情,就是初始化GDT和IDT。这里面,关键的是Windows使用的是Flat Memory Mode,也就是其保护模式下,所有段的基地址都一样。这点和其内存管理的机制息息相关,这边就先提一下。

虽然系统已经进入了保护模式,不过,此时的NTLDR还需要依赖一些BIOS调用,来访问磁盘以及显示系统。如果磁盘是SCSI的,而BIOS调用无法访问此类磁盘,那么NTLDR就加载Ntbootdd.sys来替代boot code中的磁盘访问代码。NTLDR和Boot Sector类似,也包含了NTFS和FAT文件系统的只读代码,区别么,其稍有进步,就是能访问子目录了。

由于从Windows2000开始,都有了“休眠”(Hibernation)这种关机方式。于是,NTLDR需要检查系统上是否存在有效的 Hiberfil.sys文件,如果有,那么表明最近一次关机是以“休眠”的方式关机的。于是,NTLDR就开始走“捷径”:读入 Hiberfil.sys文件,然后直接跳转到内核中“唤醒休眠”的代码,从而启动计算机。

正常启动的情况下,NTLDR读入boot.ini文件。如果该文件表明有多个可启动选项,于是就显示启动菜单,供用户选择。

这里又有一个可能的例外,虽然现在这个可能性已经很小了。这个例外就是有DOS的启动选项(包括Win9x和ME系列)。这个情况下,NTLDR 加载 Bootsect.dos文件,转回实模式,并且跳转到该文件中的MBR代码。这时候,就和最开始启动的状态(读入MBR)一样了,从而启动相应的OS。

在用户选择了启动菜单后,NTLDR还要根据该项的参数做一些相应的操作。对于这些参数么,这里就不作说明和解释了。

NTLDR加载并执行Ntdetect.com。该程序是一个16位保护模式的程序,通过BIOS调用,获取系统硬件的信息(比如总线类型啊,系统时间啊,磁盘驱动器啊,并口串口啊等等),然后将这些信息集中起来,返回给NTLDR,并且这些信息在启动的后期会保存到注册标的HKLM\ HARDWARE \DESCRIPTION下。

貌似上面的这些工作都是在后台做的,除了那个可能出现的启动菜单外,其他工作都是用户看不到的。接下来,就该给用户一些反馈信息了。

NTLDR先清屏,然后显示“Starting Windows”和进度条。这里,2000和XP/2003有所不同。2000会显示黑白屏的进度条,这时候屏幕上还没有Windows的logo。而 XP/2003会显示带有Windows logo的彩屏进度条,需要注意的是,NTLDR在开始加载任何“启动驱动”(boot driver)之前,进度条一直是空的。

还有大家可能注意到过的,就是在显示“Starting Windows”的时候,下面还会显示“For troubleshooting and advanced startup options for Windows, press F8.”,然后进度条出现并开始滚动(前进)的时候,就没有机会按F8来进入安全模式之类的了。其实想象,这里面还是有原因的。因为在系统开始加载驱动之前,主要做的事情只是加载内核文件和注册表的System hive。这两个事情和安全模式之类的其他启动方式没有关系,无论是安全模式还是标准启动,都需要加载这两部分东西。而安全模式和标准模式的区别,在于其加载的驱动有所不同。所以,一旦Windows开始加载那些boot driver之后,就无法在改变模式了。


在NTLDR从显示“Starting Windows”开始,需要经过以下步骤:

1. 加载正确的内核以及HAL(默认为Ntoskrnl.exe和Hal.dll)。如果NTLDR在加载这两个文件的过程中出错,无法完成加载,那么会显示下面这条出错信息:Windows could not start because the following file was missing or corrupt,并且会告诉你无法加载的文件名。

2. 从\Windows\System32\Config\System读入System hive。
注:hive是指一个包含了注册表中某个子树的文件。

3. 在System hive中找出所有的boot driver(这类driver的start值为0,即SERVICE_BOOT_START)。系统的所有driver都在注册表的HKLM\ SYSTEM\CurrentControlSet\Services下面有对应的子键(subkey)。

4. 加载boot drivers所在分区的文件系统驱动,以便于之后的boot driver的加载。

5. 加载boot drivers。这时候,才会开始更新屏幕上的进度条。对于Windows 2000来说,就是那个黑白进度条。

6. 设置CPU寄存器,并且跳转到Ntoskrnl.exe的入口。

好,NTLDR的任务总算完成了,接下去就全部交给Ntoskrnl了。当然,在转交控制权的时候,自然也将对方需要的信息(包括内存布局,硬件信息,System hive等)也都交给Ntoskrnl,这样,NTLDR才完成了它的使命
山东蓝鸟贵薪 2011-08-04
  • 打赏
  • 举报
回复
WIN内核研究起来真有点难呀
继续学习中...............
山东蓝鸟贵薪 2011-08-04
  • 打赏
  • 举报
回复
[Quote=引用 88 楼 zlcp520 的回复:]
容存入剪贴板
[/Quote]
详细一点...........
gyk120 2011-08-04
  • 打赏
  • 举报
回复
另外360的确有技术,有空你可以看看achills大神以前发的文章,360不是SSDT那些破烂货
SSDT现在的确是小孩子玩的,比如我这种小孩子
gyk120 2011-08-04
  • 打赏
  • 举报
回复
LS的……
360不是SSDT框架……是KiFastCallEntry……
您要是这都不懂的话,还是少说两句吧,省得被人笑……
加载更多回复(92)

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧