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

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

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

    本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...

  2. 驱动开发:内核枚举Minifilter微过滤驱动

    Minifilter 是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的sfilter文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微过滤驱动使 ...

  3. java框架之SpringCloud(1)-微服务及SpringCloud介绍

    微服务概述 是什么 业界大牛 Martin Fowler 这样描述微服务: 参考[微服务(Microservices)-微服务原作者Martin Flower博客翻译]. 下面是关于上述博客中的部分重 ...

  4. 「 从0到1学习微服务SpringCloud 」08 构建消息驱动微服务的框架 Spring Cloud Stream

    系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」01 一起来学呀! 「 从0到1学习微服务SpringCloud 」02 Eureka服务注册与发现 「 从0到1学习微服务S ...

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

    Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...

  6. Django - Django框架 简单介绍

    Django框架 简单介绍 本文地址: http://blog.csdn.net/caroline_wendy/article/details/29172271 1. 介绍 Django是一个开放源码 ...

  7. Go语言Web框架gwk介绍 3

    Go语言Web框架gwk介绍 (三)   上一篇忘了ChanResult ChanResult 可以用来模拟BigPipe,定义如下 type ChanResult struct { Wait syn ...

  8. vue对比其他框架详细介绍

    vue对比其他框架详细介绍 对比其他框架 — Vue.jshttps://cn.vuejs.org/v2/guide/comparison.html React React 和 Vue 有许多相似之处 ...

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

    引: 之前使用nose框架时,一直使用--logging-config的log文件来生成日志,具体的log配置可见之前python nose测试框架全面介绍四. 但使用一段时间后,发出一个问题,生成的 ...

随机推荐

  1. Labview实现字符串加密

    Labview实现字符串加密 对字符串进行加密,规则是每个字母后移5 位 例如A 变为F,b 变为g,x 变为c,y 变为d- 实现效果 后端实现

  2. 硬件描述语言Verilog设计经验总结

    一.硬件描述语言Verilog 粗略地看Verilog与C语言有许多相似之处.分号用于结束每个语句,注释符也是相同的(/* ... */和// 都是熟悉的),运算符"=="也用来测 ...

  3. webpack对样式的处理

    原文地址:https://github.com/zhengweikeng/blog/issues/9 我们可以在js中引入样式文件 require('myStyle.css') 这时我们便需要引入相应 ...

  4. IT安全的本质

    (1)信任:服务端信任客户端的请求参数. (2)可控:客户端的请求参数可以被控制,任意修改. 服务端信任+客户端可控 =不安全. 服务端信任+客户端不可控=安全. 服务端不信任+客户端可控=安全. 服 ...

  5. 寻找“水王”--c++

    一.题目与设计思路 三人行设计了一个灌水论坛.信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子.坊间风闻该“水王”发帖数目超过了帖子数目的一 ...

  6. Java应用的优秀管理工具Maven的下载安装及配置

    1.进入Maven的官方下载地址:http://maven.apache.org/download.cgi 2.向下滚动页面,点击这个zip包进行下载: 3.将压缩包解压后剪切到Mac的某个目录下就完 ...

  7. 查看JVM内存

    你知道如何进行JVM内存查看,这里和大家分享几个JVM内存查看方法,希望对你的学习有所帮助,通常情况下可以用代码查看,也可以在eclipse中增添相关信息后直接查看. JVM内存查看方法 可以用代码查 ...

  8. 【数据结构】通用的最小堆(最大堆)D-ary Heap

    听说有一种最小(大)堆,不限于是完全二叉树,而是完全D叉树,名为D-ary Heap(http://en.wikipedia.org/wiki/D-ary_heap).D可以是1,2,3,4,100, ...

  9. Sencha Touch 2.4 callParent() 用法

    callParent() 用法 方法介绍 用来调用父类的同名方法,并传参,这在从一个框架类派生且要重写诸如onRender这样的方法时会经常看到. 传参方式 1.arguments Ext.defin ...

  10. 数位DP之小小结

    资料链接:http://wenku.baidu.com/view/9de41d51168884868662d623.html http://wenku.baidu.com/view/d2414ffe0 ...