简易文件审计工具的设计与实现 第7页
第三章 文件过滤驱动程序
3.1 FileSpy简介
FileSpy 是由微软提供的一个可加载在系统上的文件系统过滤驱动(IFS filter driver),它可读写底层的I/O操作。我们可以在微软的IFS DDK开发包中找到它。它允许用户监控本地和网络的驱动,进行查看系统中正在处理的IRP(输入输出请求包)和Fast I/O 操作。
并且,FileSpy给出了用户读写文件过滤驱动的例子。驱动程序加载在I/O堆栈中,记录了正发生在IO操作信息。例如,开始时间,完成时间,返回值等等。
由于,FileSpy的代码量就有近万行,每行代码都理解过来就已将相当不易,在此不可能做出详细的分析过程。所以只是分析对本工具关系比较大的地方。
3.2 FileSpy分析
3.2.1 程序框架
FileFpy.h
包含了所有结构体,常量的定义。它为内核过滤驱动和运用程序所共享。
FspyKern.h
包含了所有的全局变量,还有内核函数的声明。
FileSpy.c
包含了过滤驱动的实现部分,比如驱动的入口点,回调例程等等。
FSpyLib.c
包含了驱动的帮助例程,比如,加载驱动器函数,卸载驱动器函数,监听例程,等等。
3.2.2 绑定驱动器
在FileSpy中通过SpyAttachToFileSystemDevice函数来挂载给出的文件系统设备。该函数声明如下:
第一个参数给出所要挂载的设备,第二个参数包含了该设备的名字。下面来看看这个函数的处理过程:
为了跳过文件系统识别器。文件系统识别器是文件系统驱动的一个很小的替身。为了避免没有使用到的文件系统驱动占据内核内存,windows系统不加载这些大驱动,而代替以该文件系统驱动对应的文件系统识别器。当新的物理存储媒介进入系统,I/O管理器会依次的尝试各种文件系统对它进行“识别”。识别成功,立刻加载真正的文件系统驱动,对应的文件系统识别器则被卸载掉。对我们来说,文件系统识别器的控制设备看起来就像一个文件系统控制设备。但我们不打算绑定它。分辨的方法是通过驱动的名字。凡是微软的标准的文件系统识别器的驱动对象的名字都为“\FileSystem\Fs_Rec”。看如下代码:
接下来创建一个设备用于绑带给出的设备:
接下去,开始执行加载:
3.2.3 读写操作的捕获
在文件操作中,最重要的两种动作就是读和写,所以文件审计工具对这两种动作的捕获也是不可缺少的。而当操作系统的运用层调用读写函数是,它们都会发送IRP包到底层驱动。现在我们处理IRP_MJ_READ和IRP_MJ_WRITE,如果审计工具已经绑定了卷,那么显然,发送给卷的请求就会先发送给过滤驱动。处理IRP_MJ_READ 和IRP_MJ_WRITE,能捕获文件的读写操作。
进入SfRead ()和SfWrite 函数(假设你注册了这两个函数来处理读写请求),首先判断这个设备是不是绑定卷设备。如果是,那么就是一个读写文件的操作。
过滤驱动可以这么判断是否为一个读写操作:
前面讲过了,假设注册了SfRead和SfWrite两个函数进行处理读写操作。下面我们列出这两个函数的声明,然后详细说明函数的实现过程。
在SfRead我们可以得到一个IRP,该IRP下有一个FileObject指针,它指向一个文件对象。我们可以通过该文件对象得到文件名,文件的长度等信息。然而这些信息必须在被我们所挂载的驱动程序返回时才是有效的。所以我们还必须设置完成例程。
3.2.4 文件和目录的生成打开、关闭与删除
上一小节已经分析了读,写与读类似。文件系统还有其他的操作。比如文件或目录的打开(打开已经存在的或者创建新的)、关闭。文件或目录的移动,删除。实际上FILE_OBJECT 并不仅仅指文件对象。在Windows文件系统中,目录和文件都是用FileObject 来抽象的。
这里产生一个问题,对于一个已经有的FileObject,我如何判断这是一个目录还是一个文件呢?对于一个已经存在的FileObject,我没有找到除了发送IRP
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] 下一页