每个minifilter驱动程序必须具有称为altitude的唯一标识符。 此值在驱动的inf文件中定义,例如:Instance1.Altitude = "370030"
当加载微过滤器驱动程序时,微过滤器驱动程序的高度定义其相对于I/O堆栈中其他微过滤器驱动程序的位置。高度是一个无限精度的字符串,被解释为十进制数字。具有较低数值高度的微过滤器驱动器被加载到具有较高数值的微过滤器驱动器下方的I/O堆栈中。
高度越低,加载越早。
下图显示了带有过滤器管理器和三个微过滤器驱动程序的简化I/O堆栈:
微过滤器驱动程序可以过滤基于IRP的I/O操作以及快速I/O和文件系统过滤器回调操作。对于它选择过滤的每个I/O操作,minifilter驱动程序可以注册操作前回调例程,后操作回调例程或两者。
假设上图中的所有三个微过滤器驱动程序都注册了相同的I/O操作,过滤器管理器将按照从高到低(A,B,C)的高度顺序调用其操作前回调例程,然后转发I/O请求下一个较低的驱动程序进行进一步处理。当过滤器管理器收到完成的I/O请求时,它会以相反的顺序从最低到最高(C,B,A)调用每个minifilter驱动程序的后操作回调例程。
在系统运行时,可以通过服务启动请求:
或通过显式加载请求
加载minifilter驱动程序时会调用minifilter驱动程序的DriverEntry例程,因此minifilter驱动程序可以执行初始化,该初始化将应用于minifilter驱动程序的所有实例。在其DriverEntry例程中,minifilter驱动程序调用FltRegisterFilter向过滤管理器注册回调例程,和FltStartFilter通知过滤管理器minifilter驱动程序已准备好开始附加到卷并过滤I/O请求。
在挂载卷后的第一个创建操作上调用其InstanceSetupCallBack例程,自动通知微过滤器驱动程序有关可用卷的信息。
停止过程如下:
如果minifilter驱动程序注册了InstanceTeardownStartCallback回调例程,则过滤管理器会在卸载过程开始时调用它
在卸载期间,任何当前正在执行的操作前或操作后回调例程继续正常处理,等待后操作回调的任何I/O请求可以被排空或取消,并且由微过滤器驱动程序生成的任何I/O请求继续正常处理直到他们完成。
如果minifilter驱动程序注册了InstanceTeardownCompleteCallback例程,则过滤管理器会在完成所有未完成的I/O操作后调用此例程。在此例程中,minifilter驱动程序将关闭所有仍处于打开状态的文件。
释放所有对实例的未完成引用后,过滤管理器将删除剩余的上下文,并且实例将完全拆除。
在系统运行时,可以通过服务停止请求:
或 通过显式卸载请求
卸载minifilter请求。
卸载minifilter驱动程序时会调用minifilter驱动程序的FilterUnloadCallback例程。此例程关闭所有打开的通信服务器端口,调用FltUnregisterFilter,并执行任何所需的清理。注册此例程是可选的,但是,如果minifilter驱动程序未注册此例程,则无法卸载minifilter驱动。
MiniFilter注册相关代码实现
以下是API的声明:
注意第二个参数FLT_REGISTERATION结构体。
此结构体包含了minifilter所用到的回调函数,除了size和version参数不为空且固定以外,其余参数皆可为NULL。
size处固定填sizeof(FLT_REGISTRATION)
version处固定填FLT_REGISTRATION_VERSION
Flags处一般为NULL
ContextRegistration处是一个FLT_CONTEXT_REGISTRATION结构的变长数组,用于标明minifilter使用的上下文类型。数组必须以{FLT_CONTEXT_END}结尾,在分配上下文时会使用到。示例如下:
OperationRegistration是一个FLT_OPERATION_REGISTRATION结构的变长数组,每个IRP请求类型对应一个,minifilter为它注册预操作和后操作。数组中的最后一个元素必须以{IRP_MJ_OPERATION_END}结尾,示例如下:
FilterUnloadCallback注册过滤器的卸载例程,如果为NULL的话,则minifilter不能卸载。
InstanceSetupCallback是minifilter安装的回调例程,每个卷要加载都会经过此例程的处理。
其余参数用的不多,自己也不太了解
minifilter通过通信端口进行用户模式和内核模式之间的通信。
FltCloseClientPort
FltCloseCommunicationPort
FltCreateCommunicationPort
FltSendMessage
拿下面代码作讲解:
这一套就是一个固定的流程,着重看一下FltCreateCommunicationPort这个函数
Filter 这里填FltRegisterFilter返回的过滤器的句柄
ServerPort 这里生成一个用于通信的端口
ObjectAttributes 指向OBJECT_ATTRIBUTES结构的指针
ConnectNotifyCallback 当用户模式应用程序向驱动发送连接请求时,minifilter就会调用此例程
DisconnectNotifyCallback 当用户态与内核态连接结束时,minifilter会调用此例程
MessageNotifyCallback 当用户态与内核态传送数据时,用户模式程序调用FilterSendMessage通过客户端端口向minifilter驱动程序发送消息,minifilter会调用此例程
MaxConnections 此端口允许的最大并发客户端连接数,此参数必需,且必须大于0
详细了解一下接收消息,该函数定义如下:
InputBuffer 是接收到的缓冲区
InputBufferLength 接收到的缓冲区长度
OutputBuffer 如果minifilter需要回复数据,注意,OutputBuffer是指向用户模式缓冲区的指针,此指针仅在用户模式过程的上下文中有效,并且只能从try/except块中访问。minifilter调用ProbeForWrite来验证这个指针,但是他不能确保缓冲区正确对齐。如果缓冲区包含具有对齐要求的结构,minifilter驱动程序负责执行任何必要的对齐检查。为此,minifilter驱动程序可以使用IS_ALIGNED宏。
OutputBufferLength OutputBuffer指向缓冲区的大小
ReturnOutputBufferLength 接收OutputBuffer指向的缓冲区中返回的字节数
minifilter驱动程序使用FltSendMessage例程向等待的用户模式应用程序发送消息
ClientPort 指向连接端口的指针,此参数详情看FltCreateCommunicationPort函数的ConnectNotifyCallback项,该函数指针中的有一个ClientPort参数。
SenderBuffer 指向缓冲区的指针,该缓冲区包含要发送到用户模式程序的消息。
SenderBufferLength SenderBuffer指向缓冲区的大小
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2019-2-14 17:47
被TopC编辑
,原因: