Minifilter微过滤框架:框架介绍以及驱动层和应用层的通讯

minifilter是sfilter后微软推出的过滤驱动框架。相比于sfilter,他更容易使用,需要程序员做的编码更简洁。
系统为minifilter专门制作了一个过滤管理器,这个管理器本身其实是一个传统过滤驱动,它向minifilter的使用者提供许多接口,让原本复杂的文件过滤驱动变得方便简单。之所以简单是因为传统的过滤驱动把大量的工作放在绑定设备上,而现在这些工作都交给minifilter中的过滤管理器来完成。
缺点:纯粹的使用minifilter提供的接口看不见设备对象和IRP的,所以编程自由度不大。
对minifilter的编写的第一步是向过滤管理器注册一个微过滤器,这个未过滤器是一个组件,包含了一些在文件操作的时候可能需要的回调函数。
驱动入口中最简单的版本是只包含两个函数:注册函数和开始函数。

[cpp] view plain copy

  1. NTSTARTUS DriverEntry(__in PDRIVER_OBJECT DriverObject,__in PUNICODE_STRING RegistryPath)
  2. {
  3. NTSTATUS status;
  4. UNREFERENCED_PARAMETER(registryPath);
  5. status = FltRegisterFilter(DriverObject,&FilterRegisteraion,&gFilterHandle);
  6. ASSERT(NT_SUCCESS(status));
  7. if(NT_SUCCESS(status)){
  8. status = FltStartFiltering(gFilterHandle);
  9. if(!NT_SUCCESSS(status)){
  10. FltUnregisterFilter(gFilterHandle);
  11. }
  12. }
  13. return status;
  14. }

1.注册函数FltRegisterFilter
它的第二个参数是个结构体要自己填写完整,这个结构体中的内容包含微过滤器的方方面面。
上面说的结构名字叫FLT_REGISTRATION,这个结构中有些部分是基本信息,有些部分是回调函数。所以这个结构有点面向对象语言中类的感觉。这个结构中最NB(中文意思是“重要”)的字段就是FLT_OPERATION_REGISTRATION(大家都知道,当操作系统要对文件系统进行操作的时候,其实就是通过发送各种各样的事件请求(IRP),而文件系统就负责处理好这些请求),而字段FLT_OPERATION_REGISTRATION就是一个事件请求数组(这个数组包含该过滤驱动可以处理的所有事件),每个数组元素本身又是一个五元组,包括1.当前要处理的事件,2.标识位(这个标志位一般写0,表示全过滤,还有两种值分别是不过滤缓存读写和不过滤页读写操作),3.事件被处理前函数(Pre-operation),4.事件被处理完成后的函数(Post-operation)。
【关于过滤函数:现在的过滤函数是有标准格式的(??是吗?),因为现在访问不到IRP,所以minifilter设置了一个结构用来存放请求包中的所有信息,在个结构往往是过滤函数的第一个参数。。。。传统的过滤驱动,和对应的请求相绑定的直接处理函数的格式好像也是固定的。。。想自定义处理函数格式也行,就要封装在第一级处理函数里面。】
第一个参数是知道我们自己的这个驱动的驱动对象。这个对象是我们的驱动在初始化的时候,系统帮我们生成的。
第三个参数是一个输出值,当我们的驱动成功的注册的时候,这个参数就是指向我们的微过滤驱动的句柄。

2.开始函数FltStartFiltering
就一个参数——过滤驱动的句柄,就是上面注册函数的输出值。

自己编写设备过滤驱动,说白了就是自己编写想要过滤的事件的预处理(pre-operation)或者完成(post-operation)函数。就像上面介绍的,对应每一个事件的预处理和完成函数都在结构FLT_REGISTRATION中的FLT_OPERATION_REGISTRATION结构里声明好的。
所以我们只要编写出每一个在FLT_OPERATION_REGISTRATION中给出的预处理和完成函数的函数体就行了。
比如在FLT_OPERATION_REGISTRATION中我们写了一个字段{IRP_IO_CREATE,0,NPPreCreate,NPPostCreate}。这里我们就针对事件IRP_IO_CREATE设置了这个事件的预处理函数NPPreCreate和完成函数NPPostCreate。
作为简单的例子,下面实现NPPreCreate:

[cpp] view plain copy

  1. FLT_PREOP_CALLBACK_STATUS NPPreCreate(
  2. __inout PFLT_CALLBACK_DATA Data,
  3. __in PCFLT_RELATED_OBJECTS FltObjects,
  4. __deref_out_opt PVOID *CompletionContext
  5. )
  6. {
  7. ...
  8. Data->IoStatus.Status = STATUS_ACCESS_DENIED;
  9. Data->IoStatus.Information = 0;
  10. return FLT_PREOP_COMPLETE;
  11. }

这里就是一个过滤函数的框架,先看下这个函数的参数表。第一个参数是最重要的,PFLT_CALLBACK_DATA Data。对于接触过传统sfilter框架过滤驱动的朋友一定知道,在我们的过滤驱动过滤到上层发来的请求时,拦截到的就是一个IRP请求包,这个包中有这一次请求的几乎所有信息。现在在MINIFILTER框架中,眼前的这个参数就是当年的IRP,只是变了名字,我们操作时需要的(IRP)信息都在这个结构里。
一次文件请求操作的基本原理:
对于没接触过文件过滤驱动的朋友,这里简单说下文件过滤驱动的工作原理。当上层发生了某些文件系统请求的时候,这个请求会打包成IRP,发给底层的文件系统处理,当任务处理完的时候,文件系统会把任务完成情况打成IRP包回发给上层,通知上层请求被处理了。当我们把自己编写的过滤驱动安装到文件系统上后,我们的过滤驱动就可以拦截到IRP。这个时候,我们可以打开看看IRP里的东西,做点记录,然后什么都不改变的把IRP继续往下发,当然,也可以直接填写IRP中的一些字段然后直接回发给上层,上层收到IRP后就认为上一次的请求结束了,它根本不管这个IRP是不是文件系统发给他的。
所以大家可以看到上面的例子函数里,填写了PFLT_CALLBACK_DATA结构中的两个字段。最后的返回值FLT_PREOP_COMPLETE就表示请求已经结束了,不用再把IRP往下传了。
在minifilter中,我们除了要自己编写希望过滤的请求的预处理和完成函数。还有其他的回调函数可以编写,不过他们都是可选的,不一定要实现。具体有哪些这里就不列举了。

MINIFILTER的另一个特色:与应用层的通信
我们在编写文件过滤驱动的时候,不免会经常和上层的应用程序进行通信,在传统的文件过滤驱动框架中,想要实现驱动层和应用层的通信一般都是通过DiviceIoControl配合内核模块中的处理控制请求,或者申请一块共享存储区实现,都比较麻烦。minifilter中专门提供了通信用的API,并且这种API在使用的时候,就像是网络编程中的socket通信一样方便简单。
下面的代码是建立一个通信端口的过程:

[cpp] view plain copy

  1. PSECURITY_DESCRIPTOR sd;
  2. OBJECT_ATTRIBUTES oa;
  3. status = FltBuildDefaultSecurityDescriptor(&sd,FLT_PORT_ALL_ACCESS);
  4. if(!NT_SUCCESS(status)){
  5. goto final;
  6. }
  7. RtlInitUnicodeString(&uniString,MINISPY_PORT_NAME);
  8. InitializeObejectAttributes(&oa,&uniString,OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,NULL,sd);
  9. status = FltCreateCommunicationPort(gFilterHandle,&gServerPort,&oa,NULL,NPMiniConnect,NPMiniDisconnect,NPMiniMessage,1);

首先函数FltBuildDefaultSecurityDescriptor是用来申请一个安全叙述子(额,简单点,就是给使用通信端口的用户申请个权限,这里可以看到申请的权限是FLT_PORT_ALL_ACCESS,意思就是:用户层的程序连接到设置了这个权限级别的通信端口后,可以获得所有操作权限)。
下面的InitializeObejectAttributes就是用来给我们要创建的对象(名称是:MINISPY_PORT_NAME)设置一些属性值。
最后最重要的FltCreateCommunicationPort就是给这个端口定义所需要的三个函数,同时注册这个端口(注册了才能用)。这里注册的三个函数分别是:
NPMiniConnect用户层和内核层建立连接的时候会调用该函数 
NPMiniDisconnect用户层和内核层断开连接的时候会调用该函数 
NPMiniMessage用户层和内核层进行通讯的时候会调用
当然,既然称他们为回调函数,那他们就不是我们用户层的程序去调用的,工作原理是这样的,我们在用户层通过两个api:FilterConnectCommunicationPort和FilterSendMessage来发出请求,然后通讯端口会根据我们的请求自己去调用这三个函数完成具体的工作。其中前者对应NPMiniConnect,后者对应NPMiniMessage。
完成上面三个回调函数后,内核中的通讯代码已经准备好了。
下面就是完成通讯的另一端内容:用户层(应用层)。这里要注意的是在编写程序的时候,需要包含几个minifilter必须的头文件和库文件:FltUser.h,fltLib.lib,fltMgr.lib,具体如下:
#include <FltUser.h>
#progma comment(lib,"fltLib.lib")
#progma comment(lib,"fltMgr.lib")
后面的代码需要了解的就是一个简单的流程:先FilterConnectCommunicationPort连接上目标端口,再FilterSendMessage发送消息。原理就介绍这么多,具体的代码在下载连接中,其中,用户层和通讯端口的连接是做成了dll,首先要生成dll,然后要使用dll就用哪个app工程,里面会装载dll。另一个minifilter可以生成一个sys系统文件,把系统文件用inf文件安装上,并在cmd里面输入net start XXX(这里是sys的文件名,其实是服务名,只不过两个名称大部分情况下是一样的)通讯端口就打开了,然后app就可以试着连接和通讯了。

minifilter代码下载http://download.csdn.net/detail/arvon2012/4687632
技术相关更多文章猛击:哇啦天堂论坛技术区

http://blog.csdn.net/arvon2012/article/details/7926366

时间: 2024-12-21 03:57:58

Minifilter微过滤框架:框架介绍以及驱动层和应用层的通讯的相关文章

2、CC2541芯片中级教程-OSAL操作系统(进一步了解-OLED &amp;&amp; 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~

本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 中级教程-OSAL操作系统(OSAL系统解基本套路) 中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~ 中级教程-OSAL操作系统(ADC-光敏电阻) OSAL操作系统-实验16 串口波特率扩展 OSAL操作系统-实验1

Django - Django框架 简单介绍

Django框架 简单介绍 本文地址: http://blog.csdn.net/caroline_wendy/article/details/29172271 1. 介绍 Django是一个开放源码的Web应用框架, 由Python写成. 採用了MVC的软件设计模式, 即模型M, 视图V和控制器C. 它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的站点的, 并于2005年7月在BSD许可证下公布. 这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的.

.NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍

Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器学习算法以及提供计算机视频.音频.信号处理以及统计应用相关的解决方案.该项目使用C#语言编写,项目主页:http://accord-framework.net/ 说明:该文章只是一个基本介绍,主要内容是翻译的官方文档和介绍,部分英文表述个人能力有限,不太熟悉,所以直接照搬原文,有比较确切的知道中文名

python nose测试框架全面介绍七--日志相关

引: 之前使用nose框架时,一直使用--logging-config的log文件来生成日志,具体的log配置可见之前python nose测试框架全面介绍四. 但使用一段时间后,发出一个问题,生成的报告只有错误提示,没有日志,查看nose的官网,nose默认支持将日志显示的,如下: 脚本如下: #coding:utf-8 ''' Created on 2016年6月22日 @author: huzq ''' import logging from test_case import new fr

关于jsp商城开发中一些常用框架的介绍

Struts跟Tomcat.Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点,使java商城产品以及jsp商城开发者能更深入的了解其内部实现机制.除此之外,在 java商城开发 中Struts的优点主要集中体现在两个方面:Taglib和页面导航.Taglib是Struts的标记库,比较灵活,能大大提高开发效率.另外,就目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点.struts历经6年多的发展,是目前用户数最

上课笔记_Ajax框架,DWR介绍,应用,例子

使用Ajax框架 1. 简化JavaScript的开发难度 2. 解决浏览器的兼容性问题 3. 简化开发流程 常用Ajax框架 Prototype 一个纯粹的JavaScript函数库,对Ajax提供良好支持 jQuery 1.非常优秀的JavaScript库,对Ajax提供了良好的支持 2.与Prototype设计思想不同的是在使用jQuery之后,开发者操作的不再是DOM对象而是jQuery对象 DWR 1.        非常专业的Java Ajax框架 2.        通过DWR框架

家庭洗车APP --- Androidclient开展 之 网络框架包介绍(一)

家庭洗车APP --- Android客户端开发 之 网络框架包介绍(一) 上篇文章中给大家简单介绍了一些业务.上门洗车APP --- Android客户端开发 前言及业务简单介绍,本篇文章给大家介绍下网络框架.之前也了解过一些开源网络通讯架构.也大概看了一部分源代码.比方Afinal.Volley.AndBase.Android-async-http等,感觉各自都有各自的优劣,自己也曾封装过一些简单的网络架构,感觉有非常多地方须要注意和优化.这里就不贴出来献丑了,感兴趣的朋友能够去查阅学习上面

webUI自动化测试框架---”pyswat“介绍

webUI自动化测试框架---"pyswat"介绍 大家好我是lamecho 辣么丑,今天给大家介绍一款web自动化测试框架pyswat.  "pyswat"是一个做web页面自动化测试的框架(python-selenium-web-auto-test缩写).基于python,利用hook技术及对selenium封装,做到完全录制案例(操作步骤)不需要手写脚本,很方便有木有!:lol 举个栗子,做网站登录操作在python中你要这样写一大堆脚本 而通过pyswat的

开源实体映射框架EmitMapper介绍

开源实体映射框架EmitMapper介绍 综述 EmitMapper是一个开源实体映射框架,地址:http://emitmapper.codeplex.com/. EmitMapper映射效率比较高,接近硬编码.EmitMapper采用emit方式在运行时动态生成IL,而其他映射框架多是采用反射机制.此外EmitMapper最大限度地减少了拆箱装箱操作和映射过程中的额外的调用. EmitMapper支持.net的所有平台:Framework 3.5.Microsoft Silverlight 3