-
-
[原创] MiniFilter架构及其文件过滤原理分析 (update 1/12)
-
发表于: 3天前 520
-
MiniFilter 架构的解析将从 (1) 初始化阶段的 Frame 初始化与卷抽象-设备栈附加,(2) Filter 注册, (3) Instance 实例化, (4) 回调函数触发等方面进行较为深入、细致的分析。
1. VolumeAttach
FltpFsNotificationActual 是 fltMgr.sys 在响应文件系统挂载事件时,自动为 Minifilter 创建实例并附加到卷设备栈的核心路径。这是 Minifilter 实现“挂载时自动绑定(Auto-Attach)”机制的底层实现。FltpFsNotificationActual 函数的触发时机如下:

1.1 Path1: Initialization
fltMgr 在系统 Phase1 初始化阶段被加载,在完成自身初始化时会遍历当前已注册的所有文件系统,并为每个文件系统设备栈挂载设备对象,创建卷抽象与 frame 进行绑定。
KiStartSystemThread -> PspSystemThreadStartup -> Phase1Initialization -> IoInitSystem -> IoInitSystemPreDrivers -> IopInitializeBootDrivers -> IopInitializeBuiltinDriver -> FLTMGR!GsDriverEntry -> FLTMGR!DriverEntry -> FLTMGR!FltpAttachFrame -> FLTMGR!FltpFsNotificationActual -> FLTMGR!FltpAttachToFileSystemDevice -> FLTMGR!FltpAttachDeviceObject -> nt!IoAttachDeviceToDeviceStackSafe
filMgr 在初始化阶段,调用函数 FltpAttachFrame 创建一个 FrameZeroAltitude 的 frame。当后续注册 filter 时,fltMgr 会通过读取注册表中的 altitude 值来动态扩展 frame->AltitudeIntervalHigh。该函数内部调用 IoRegisterFsRegistrationChangeMountAware 向文件系统注册通知回调例程(FltpFsNotification),当文件系统注册或注销时触发。接着,调用 IoGetDeviceObjectPointer 函数获取目标表设备栈顶层的设备对象(包括 "\\Device\\RawDisk" 和 "\\Device\\RawCdRom"),调用 FltpFsNotificationActual 函数(获取设备对象名并调用 FltpAttachToFileSystemDevic)执行附加。
函数 FltpAttachToFileSystemDevic 调用 FltpCreateVolumeDeviceObject 创建设备对象用于向目标设备栈中进行插入。
函数
FltpCreateVolumeDeviceObject调用 IoCreateDevice 创建设备对象,并设置 device->DeviceExtension(_VOLUME_DEVICE_EXTENSION)。接着,调用函数 FltpInitVolume 初始化 volume 并与 frame 进行绑定(通过_VOLUME_DEVICE_EXTENSION)。函数
FltpAttachDeviceObject调用 IoAttachDeviceToDeviceStackSafe 进行设备栈插入。调用 FltpDoFilterNotificationForNewVolume/FltpEnumerateFileSystemVolumes 将创建的设备对象插入文件系统设备栈。
(FltpEnumerateFileSystemVolumes)在 fltMgr 首次加载时,主动扫描当前系统中所有已挂载的磁盘设备,并尝试为每个磁盘设备关联 volume 抽象并将设备对象插入设备栈。
- 调用 IoGetDeviceAttachmentBaseRef 获取当前设备栈栈底的设备对象,调用 IoEnumerateDeviceObjectList 枚举设备对象列表。
- 遍历设备对象列表,调用 IoGetDiskDeviceObject 获取对应顶层磁盘设备对象指针。调用 FltpCreateVolumeDeviceObject+FltpAttachDeviceObject 为每个磁盘设备对象创建并绑定 volume。
- 有条件(dword_1C00295F0 > 5)调用 FltpDoFilterNotificationForNewVolume。
(FltpDoFilterNotificationForNewVolume)当一个新卷被挂载时,通知所有已注册的 minifilter,并为每个符合条件的 filter 创建新的实例并附加到该卷设备栈。通过遍历 frame->RegisteredFilters 查找所注册的 filter,调用 FltpEnumerateRegistryInstances 创建 instance 并与 volume 绑定。
1.2 Path2: MountVolume
DriverEntry 中设置 MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] 为 FltpFsControl,包含对文件系统的控制操作,如卷挂载(IRP_MN_MOUNT_VOLUME)。 动态挂载到新卷的设备栈中,函数调用路径如下:
nt!IofCallDriver -> FLTMGR!FltpFsControl -> FLTMGR!FltpFsControlMountVolume -> FLTMGR!FltpAttachDeviceObject -> nt!IoAttachDeviceToDeviceStackSafe
函数 FltpFsControlMountVolume,
- 调用 FltpLogEventWithObjectID 关联 volume-frame-device,设置 _IRP_CTRL。
- 调用 FltpPerformPreMountCallbacks 执行卷挂载的前置回调函数。
- 为向下传递的 IRP(MountVolume 请求)准备下一层 _IO_STACK_LOCATION,复制必要的参数,并注册一个在任何情况下都会被调用的完成例程(FltpFsControlCompletion),以便过滤管理器能在底层文件系统处理完挂载请求后进行后续处理。

- 调用 FltpAttachDeviceObject 将设备对象插入设备栈。
- 调用 FltpPerformPostMountCallbacks 执行卷挂载的后置回调函数。
- 调用 FltpCompleteRequest(IofCompleteRequest) 完成 IRP 处理。
1.3 Path3: RegisterFileSystem
nt!IoRegisterFileSystem -> FLTMGR!FltpFsNotification -> FLTMGR!FltpFsNotificationActual -> FLTMGR!FltpAttachToFileSystemDevice -> FLTMGR!FltpAttachDeviceObject -> nt!IoAttachDeviceToDeviceStackSafe
函数 FltpFsNotification 的逻辑较为简单,调用 FltpFsNotificationActual 执行设备栈附加。
2. Registration
函数 FltRegisterFilter 用于向 MiniFiltter 注册 filter,除了初始化 _FLT_REGISTRATION 结构体中所设置的参数外,还包括:验证 filter 的安全性(FltpInitializeFilterVerifier)、根据注册表所设置的 altitude 按顺序插入 frame->RegisteredFilters 链表。
需要注意的是,_FLT_FILTER 结构体的大小会依据所注册回调函数数量而发生拓展。

2.1 FltpGetInstanceAltitude
函数 FltpGetInstanceAltitude 中,读取注册表中实例的键用于获取 Altitude。
内部调用 FltpOpenInstancesRegistryKey 打开对应的注册表键,路径为
\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Instance.

查询名为
DEFAULTINSTANCE的子键,接着查询该子键的Altitude值,并返回字符串格式。


这也解释了为什么 MiniFilter 驱动安装时的 INF 文件的重要性。
参见: 有偿求解决,文件过滤驱动函数FltRegisterFilter调用失败返回0xc0000034的问题
2.2 FltpFindFrameForFilter
- 当 flttMgr 中还未创建 frame 时,调用函数
FltpAttachFrame设置并初始化 frame,填充 altitude,完成设备栈的插入。frame->AltitudeIntervalLow 默认为0,frame->AltitudeIntervalHigh 为当前 altitude。

- 当 frame 存在时,若 altitude 不在当前 frame 的范围内,更新当前 frame->AltitudeIntervalHigh。因此,fltMgr 只有一个 altitude 可动态扩展的 frame。

2.3 FltpLinkFilterIntoFrame
函数 FltpLinkFilterIntoFrame 依据 altitude 插入 frame->RegisteredFilters 链表。altitude 的值决定了 filter 在设备栈中的被调用顺序。

3. FltStartFiltering
函数 FltStartFiltering 用于创建 instance 并于 volume 进行关联。当设置 InstanceSetupCallback 回调时的函数执行路径如下:
FltStartFiltering -> FltpDoVolumeNotificationForNewFilter -> FltpEnumerateRegistryInstances -> FltpCreateInstanceFromName -> FltpInitInstance -> FltpDoInstanceSetupNotification -> self_func
函数 FltpEnumerateRegistryInstances 通过查询注册表的 instance 子键数来决定所需创建 _FLT_INSTANCE 对象数量 (FltpOpenInstancesRegistryKey -> \\Registry\\Machine\\System\\CurrentControlSet\\Services\\Instance)。接着,调用 FltpCreateInstanceFromName 创建 instance 对象并与 volume 绑定。

instance 子键数量由 INF 文件进行定义。

虽然当前仅有一个 instance 子键,但上层调用函数 FltpEnumerateRegistryInstances 通过遍历当前 frame->AttachedVolumes 来为每个 volume 绑定 instance。因此,即使仅设置了一个 instance,需要为每个 volume 均绑定一个 instance 对象。

3.1 FltpInitInstance
函数 FltpInitInstance 初始化 instance 并依据 MajorFunction 将回调插入 volume->Callbacks中:
函数
FltpNumCallbackNodes获取当前 filter 的有效回调数。由于 filter 所注册的回调函数数量不固定,因此申请 _FLT_INSTANCE 结构体的内存时需要获取有效回调函数数量。fiilter->Operations 实际上指向一个 _FLT_OPERATION_REGISTRATION 数组,以 0x80 为结束标志。类似的,instance->CallbackNodes 提供了一个长度为 50 的 _CALLBACK_NODE 指针表用于快速索引,而 _CALLBACK_NODE 结构体紧随 instance。

函数
FltpDoInstanceSetupNotification调用 filter->InstanceSetup 执行回调函数。函数
FltpSetCallbacksForInstance设置回调函数组。按照 MajorFunction 将 instance 的回调插入 volume 中。

Callback
FltpCreate 函数中 ,通过 _DEVICE_OBJECT::_DRIVER_EXTENSION::_FLT_VOLUME 解析设备对象所属的卷,完成 _IRP_CALL_CTRL 结构体的初始化(将作为函数 FltpPassThroughInternal 的参数)。此处的 _DRIVER_EXTENSION 实际上是 FLTMGR!_VOLUME_DEVICE_EXTENSION,由驱动程序自行定义,用于存储驱动的私有数据。

结构体 _VOLUME_DEVICE_EXTENSION 的定义如下:
1 2 3 4 5 6 | FLTMGR!_VOLUME_DEVICE_EXTENSION +0x000 Type : _FLT_TYPE +0x008 AttachedToDeviceObject : Ptr64 _DEVICE_OBJECT // 所附加的设备对象 +0x010 Frame : Ptr64 _FLTP_FRAME +0x018 VolumeAccessLock : _FAST_MUTEX +0x050 Volume : Ptr64 _FLT_VOLUME // 关联私有数据结构(卷), 用于下层函数调用 |
结构体 _IRP_CALL_CTRL 用于管理单个 IRP 在 MiniFilter 中的处理过程,包含当前 I/O 请求的上下文,其定义如下:
1 2 3 4 5 6 7 | FLTMGR!_IRP_CALL_CTRL +0x000 Volume : Ptr64 _FLT_VOLUME +0x008 Irp : Ptr64 _IRP +0x010 IrpCtrl : Ptr64 _IRP_CTRL +0x018 StartingCallbackNode : Ptr64 _CALLBACK_NODE // 处理此 irp 的第一个回调节点 +0x020 OperationStatusCallbackListHead : _SINGLE_LIST_ENTRY // 状态回调链表(如完成通知) +0x028 Flags : ICC_FLAGS |
函数 FltpPassThroughInternal 和 FltpLegacyProcessingAfterPreCallbacksCompleted 内部调用 Pre/Post 回调函数。

回调函数被触发时的调用路径:
- Pre:IofCallDriver -> FLTMGR!FltpCreate -> FLTMGR!FltpPassThroughInternal -> FLTMGR!FltpPerformPreCallbacks -> PreFunc
- Post:IofCallDriver -> FLTMGR!FltpCreate -> FltpLegacyProcessingAfterPreCallbacksCompleted -> FltpPassThroughCompletionWorker -> FltpPerformPostCallbacks -> PostFunc
FltpPerformPreCallbacks 是 fltmgr.sys 内部用于按 Altitude 从高到低依次调用 Minifilter Pre-operation 回调的核心函数,是 Minifilter 实现“有序过滤”的执行中枢。它本身不派发 IRP 到文件系统,但决定了哪些过滤器有机会拦截或修改 I/O 请求。
3. Appendix
3.1 Frame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | FLTMGR!_FLTP_FRAME +0x000 Type : _FLT_TYPE +0x008 Links : _LIST_ENTRY // 指向 FltGlobals_0xc0 ??? +0x018 FrameID : Uint4B +0x020 AltitudeIntervalLow : _UNICODE_STRING // 该 Frame 覆盖的 Altitude 下限 +0x030 AltitudeIntervalHigh : _UNICODE_STRING // 该 Frame 覆盖的 Altitude 上限 // 当 Minifilter 注册时,FLTMGR 根据其 Altitude 字符串找到对应的 Frame,并将其加入 RegisteredFilters。 +0x040 LargeIrpCtrlStackSize : UChar +0x041 SmallIrpCtrlStackSize : UChar +0x048 RegisteredFilters : _FLT_RESOURCE_LIST_HEAD // 该 Frame 内所有已注册 Minifilter 的链表头 // I/O 请求按此顺序调用 Pre 回调,反序调用 Post 回调 +0x0c8 AttachedVolumes : _FLT_RESOURCE_LIST_HEAD // 该 Frame 中所有 Filter 已 attach 的 卷(Volume)列表. 实际是 _FLT_VOLUME 对象的集合, 用于卷级资源管理. +0x148 MountingVolumes : _LIST_ENTRY // 正在挂载过程中的卷临时链表(避免竞态) +0x158 AttachedFileSystems : _FLT_MUTEX_LIST_HEAD // 已 attach 的文件系统设备(如 \Device\Ntfs)列表 +0x1a8 ZombiedFltObjectContexts : _FLT_MUTEX_LIST_HEAD // 僵尸”上下文列表 // 当 File/Stream 关闭但上下文仍有引用时暂存于此, 待引用归零后释放, 防止 Use-After-Free +0x1f8 KtmResourceManagerHandle : Ptr64 Void // KTM(Kernel Transaction Manager)资源管理器句柄 +0x200 KtmResourceManager : Ptr64 _KRESOURCEMANAGER // 指向内核 KTM 资源管理器对象, 用于支持事务 NTFS(TxF)通知 +0x208 FilterUnloadLock : _ERESOURCE +0x270 DeviceObjectAttachLock : _FAST_MUTEX +0x2a8 Prcb : Ptr64 _FLT_PRCB // 指向 Filter Manager 的 Per-Processor Control Block, 存储 CPU 局部数据(如 IRP 控制块缓存) +0x2b0 PrcbPoolToFree : Ptr64 Void // 待释放的 PRCB 内存池(延迟释放) +0x2b8 LookasidePoolToFree : Ptr64 Void // 待释放的 Lookaside List 内存 +0x2c0 IrpCtrlStackProfiler : _FLTP_IRPCTRL_STACK_PROFILER // IRP 控制栈使用分析器(调试/性能调优) +0x400 SmallIrpCtrlLookasideList : _NPAGED_LOOKASIDE_LIST // 小型 IRP 控制块(IrpCtrl)的快速分配池 +0x480 LargeIrpCtrlLookasideList : _NPAGED_LOOKASIDE_LIST // 大型 IrpCtrl 分配池 +0x500 ReserveIrpCtrls : _RESERVE_IRPCTRL // 预留的 IrpCtrl(用于内存压力下保证关键路径不失败) |
3.2 Filter
_FLT_FILTER 是 Minifilter 驱动在 Filter Manager(fltMgr.sys)内部的核心表示对象,由 FltRegisterFilter 创建。每个 filter 可包含多个 instance 实例,但 instance 实例与 Volume 一一对应。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | FLTMGR!_FLT_FILTER +0x000 Base : _FLT_OBJECT /* FLTMGR!_FLT_OBJECT +0x000 Flags : _FLT_OBJECT_FLAGS // FLT_OBFL_TYPE_VOLUME, FLT_OBFL_TYPE_INSTANCE, FLT_OBFL_TYPE_FILTER +0x004 PointerCount : Uint4B // 引用计数 +0x008 RundownRef : _EX_RUNDOWN_REF // 运行降级引用(Run-Down Reference), 允许在对象被销毁之前完成正在进行的操作。它通常用于确保在对象被释放前,所有依赖于该对象的操作都已完成。 +0x010 PrimaryLink : _LIST_ENTRY // 按照 FLT_OBJECT 进行串联 +0x020 UniqueIdentifier : _GUID */ +0x030 Frame : Ptr64 _FLTP_FRAME // filter 所属 frame. // Frame 按 Altitude 区间组织 Filters(如 370000 属于 "Anti-malware" Frame); // 决定多个 Minifilter 的调用顺序 +0x038 Name : _UNICODE_STRING +0x048 DefaultAltitude : _UNICODE_STRING // 海拔 +0x058 Flags : _FLT_FILTER_FLAGS // 控制 Filter 生命周期状态 +0x060 DriverObject : Ptr64 _DRIVER_OBJECT // Minifilter 自身的驱动对象 +0x068 InstanceList : _FLT_RESOURCE_LIST_HEAD // 该 Filter 所有活跃 Instance 的链表头, 每个卷(Volume)上 attach 一个 Instance +0x0e8 VerifierExtension : Ptr64 _FLT_VERIFIER_EXTENSION // Driver Verifier 附加的验证数据 +0x0f0 VerifiedFiltersLink : _LIST_ENTRY // 所有启用 Verifier 的 Filter 的全局链表节点 +0x100 FilterUnload : Ptr64 long // FLT_REGistration.FilterUnloadCallback +0x108 InstanceSetup : Ptr64 long // 卷挂载时调用,决定是否 attach 到该卷 +0x110 InstanceQueryTeardown : Ptr64 long // 当卷即将卸载或手动 detach 时,询问是否允许 +0x118 InstanceTeardownStart : Ptr64 void // 开始 teardown Instance(可做清理准备) +0x120 InstanceTeardownComplete : Ptr64 void // instance 完全销毁后调用 +0x128 SupportedContextsListHead : Ptr64 _ALLOCATE_CONTEXT_HEADER // 支持的上下文类型(File/Stream/Instance 等)的分配器头, 用于 FltAllocateContext 快速分配 +0x130 SupportedContexts : [7] Ptr64 _ALLOCATE_CONTEXT_HEADER +0x168 PreVolumeMount : Ptr64 _FLT_PREOP_CALLBACK_STATUS // 卷挂载前回调 +0x170 PostVolumeMount : Ptr64 _FLT_POSTOP_CALLBACK_STATUS // 卷挂载后回调 +0x178 GenerateFileName : Ptr64 long +0x180 NormalizeNameComponent : Ptr64 long +0x188 NormalizeNameComponentEx : Ptr64 long +0x190 NormalizeContextCleanup : Ptr64 void +0x198 KtmNotification : Ptr64 long // 事务 NTFS(TxF)通知回调 +0x1a0 SectionNotification : Ptr64 long // 内存映射文件(Section)事件通知 +0x1a8 Operations : Ptr64 _FLT_OPERATION_REGISTRATION // 指向 IRP 操作回调数组 // 该数组的每项都是一个 _FLT_OPERATION_REGISTRATION 结构体, 以 Operations->MajorFunction=0x80 为结束标志 +0x1b0 OldDriverUnload : Ptr64 void // 保存原始 DRIVER_OBJECT->DriverUnload // 由 FltpMiniFilterDriverUnload 代理调用, 确保卸载顺序安全 +0x1b8 ActiveOpens : _FLT_MUTEX_LIST_HEAD // 当前打开的文件句柄列表(用于 FltClose 通知等) +0x208 ConnectionList : _FLT_MUTEX_LIST_HEAD // 用户态通信连接列表(通过 FltCreateCommunicationPort 建立) +0x258 PortList : _FLT_MUTEX_LIST_HEAD // 通信端口对象列表 +0x2a8 PortLock : _EX_PUSH_LOCK typedef struct _FLT_OPERATION_REGISTRATION { UCHAR MajorFunction; // IRP 类型(未经过+22映射), https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/fltkernel/ns-fltkernel-_flt_parameters FLT_OPERATION_REGISTRATION_FLAGS Flags; // FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO(0x00000001) 跳过分页 I/O // FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO (0x00000002) 跳过 cache I/O // FLTFL_OPERATION_REGISTRATION_SKIP_NON_DASD_IO(0x00000004)跳过对非 DASD 卷 // FLTFL_OPERATION_REGISTRATION_SKIP_NON_CACHED_NON_PAGING_IO(0x00000008) 跳过未缓存或分页 I/O PFLT_PRE_OPERATION_CALLBACK PreOperation; // 函数原型: https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/fltkernel/nc-fltkernel-pflt_pre_operation_callback PFLT_POST_OPERATION_CALLBACK PostOperation; PVOID Reserved1; // NULL} FLT_OPERATION_REGISTRATION, *PFLT_OPERATION_REGISTRATION; |
3.3 Instance
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | FLTMGR!_FLT_INSTANCE +0x000 Base : _FLT_OBJECT +0x030 OperationRundownRef : Ptr64 _EX_RUNDOWN_REF_CACHE_AWARE +0x038 Volume : Ptr64 _FLT_VOLUME +0x040 Filter : Ptr64 _FLT_FILTER +0x048 Flags : _FLT_INSTANCE_FLAGS +0x050 Altitude : _UNICODE_STRING +0x060 Name : _UNICODE_STRING +0x070 FilterLink : _LIST_ENTRY // 指向所属 filter 的双循环链表 +0x080 ContextLock : _EX_PUSH_LOCK +0x088 Context : Ptr64 _CONTEXT_NODE +0x090 TransactionContexts : _CONTEXT_LIST_CTRL +0x098 TrackCompletionNodes : Ptr64 _TRACK_COMPLETION_NODES +0x0a0 CallbackNodes : [50] Ptr64 _CALLBACK_NODE // MajorFunction + 22 // 回调节点指针数组, 后续紧跟 _CALLBACK_NODE 结构体(依据有效回调函数数量动态申请) /*FLTMGR!_CALLBACK_NODE +0x000 CallbackLinks : _LIST_ENTRY // 链入同一 IRP_MJ 或回调类型的链表 +0x010 Instance : Ptr64 _FLT_INSTANCE +0x018 PreOperation : Ptr64 _FLT_PREOP_CALLBACK_STATUS +0x020 PostOperation : Ptr64 _FLT_POSTOP_CALLBACK_STATUS +0x018 GenerateFileName : Ptr64 long +0x018 NormalizeNameComponent : Ptr64 long +0x018 NormalizeNameComponentEx : Ptr64 long +0x020 NormalizeContextCleanup : Ptr64 void +0x028 Flags : _CALLBACK_NODE_FLAGS */ |
3.4 Volume
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | FLTMGR!_FLT_VOLUME +0x000 Base : _FLT_OBJECT +0x030 Flags : _FLT_VOLUME_FLAGS +0x034 FileSystemType : _FLT_FILESYSTEM_TYPE // 文件系统类型. 如 FLT_FSTYPE_NTFS=2 +0x038 DeviceObject : Ptr64 _DEVICE_OBJECT +0x040 DiskDeviceObject : Ptr64 _DEVICE_OBJECT // 指向物理磁盘的设备对象 +0x048 FrameZeroVolume : Ptr64 _FLT_VOLUME +0x050 VolumeInNextFrame : Ptr64 _FLT_VOLUME +0x058 Frame : Ptr64 _FLTP_FRAME +0x060 DeviceName : _UNICODE_STRING // "\Device\HarddiskVolume3" +0x070 GuidName : _UNICODE_STRING // "\??\Volume{7338f374-e276-45bd-9b04-34c204621c43}" +0x080 CDODeviceName : _UNICODE_STRING // "\Ntfs" +0x090 CDODriverName : _UNICODE_STRING // "\FileSystem\Ntfs" +0x0a0 InstanceList : _FLT_RESOURCE_LIST_HEAD +0x120 Callbacks : _CALLBACK_CTRL // 将与该卷所绑定的全部 instance 所设置的回调进行串联 /*FLTMGR!_CALLBACK_CTRL +0x000 OperationLists : [50] _LIST_ENTRY // 每种 IRP_MJ_xxx 均有一个双循环链表用于串联 instance +0x320 OperationFlags : [50] _CALLBACK_NODE_FLAGS */ +0x508 ContextLock : _EX_PUSH_LOCK +0x510 VolumeContexts : _CONTEXT_LIST_CTRL // 管理附加到该卷上的上下文 +0x518 StreamListCtrls : _FLT_RESOURCE_LIST_HEAD +0x598 FileListCtrls : _FLT_RESOURCE_LIST_HEAD // 管理和存储流(Stream)和文件相关的控制信息 +0x618 NameCacheCtrl : _NAME_CACHE_VOLUME_CTRL // 管理文件名缓存 +0x6d0 MountNotifyLock : _ERESOURCE // 同步卷挂载通知 +0x738 TargetedOpenActiveCount : Int4B // 记录针对该卷的活动打开操作数量 +0x740 TxVolContextListLock : _EX_PUSH_LOCK +0x748 TxVolContexts : _TREE_ROOT // 管理事务性卷上下文 +0x750 SupportedFeatures : Int4B // 该卷支持的特性集合 |
3.5 IRP_Ctrl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | FLTMGR!_IRP_CTRL +0x000 Type : _FLT_TYPE +0x004 Flags : Uint4B +0x008 LookAsideProcessorIndex : Uint4B // 分配此 _IRP_CTRL 的 CPU 核心索引,用于 Per-CPU 内存池管理 +0x00c MajorFunction : UChar +0x00d DataScanConflictRetryCount : UChar // 用于 防病毒扫描冲突重试(如多个 AV 同时锁文件) +0x00e CompletionStackLength : UChar // 当前 Completion Stack 中节点数量 +0x00f NextCompletion : UChar // 下一个要执行的 Post 回调索引(从高到低执行 +0x010 CompletionStack : Ptr64 _COMPLETION_NODE // FLTMGR!_COMPLETION_NODE 是 Windows Minifilter 架构中用于管理 Post-operation 回调的关键结构,它在 I/O 请求(IRP)完成阶段被使用,确保每个注册了 PostOperation 回调的 Minifilter 都能按正确顺序、携带正确的上下文被调用。 /*FLTMGR!_COMPLETION_NODE +0x000 IrpCtrl : Ptr64 _IRP_CTRL +0x008 CallbackNode : Ptr64 _CALLBACK_NODE +0x008 Filter : Ptr64 _FLT_FILTER +0x010 InstanceLink : _LIST_ENTRY +0x020 InstanceTrackingList : Ptr64 _COMPLETION_NODE_TRACKING_LIST +0x028 Context : Ptr64 Void +0x030 DataSnapshot : _FLT_IO_PARAMETER_BLOCK +0x078 Flags : Uint2B */ +0x018 SyncEvent : _KEVENT // 用于同步等待 IRP 完成(当 Filter 返回 FLT_PREOP_PENDING 后需手动完成) +0x030 Irp : Ptr64 _IRP +0x030 FsFilterData : Ptr64 _FS_FILTER_CALLBACK_DATA // 在 Fast I/O 或 FsFilter 路径中,指向 _FS_FILTER_CALLBACK_DATA(非 IRP 路径) +0x038 AsyncCompletionRoutine : Ptr64 void // 异步完成回调 +0x040 AsyncCompletionContext : Ptr64 Void // 异步完成上下文 +0x048 InitiatingInstance : Ptr64 _FLT_INSTANCE // 发起当前 I/O 的 Instance +0x050 PendingCallbackNode : Ptr64 _CALLBACK_NODE // 当前正在执行的 Pre 回调节点(即下一个要调用的 _CALLBACK_NODE) +0x050 StartingCallbackNode : Ptr64 _CALLBACK_NODE // 在某些路径下表示起始回调节点 +0x058 preOp : <anonymous-tag> // 临时存储 Pre/Post 回调的返回状态或参数 +0x058 postOp : <anonymous-tag> +0x060 PostCompletionRoutine : Ptr64 void +0x068 DeviceObject : Ptr64 _DEVICE_OBJECT +0x070 FileObject : Ptr64 _FILE_OBJECT +0x078 FltWork : _FLTP_WORKITEM // 用于延迟处理(如 Post 回调在 DPC/Worker 线程执行) +0x078 PendingCallbackContext : Ptr64 Void // 挂起时的回调上下文 +0x080 CachedCompletionNode : Ptr64 _COMPLETION_NODE // 预分配的 Completion 节点(用于快速路径,避免内存分配) +0x088 PendingStatus : Int4B +0x0a0 CreateIrp : <anonymous-tag> // 仅当 MajorFunction == IRP_MJ_CREATE 时有效,包含额外创建参数(如 ECP 列表、Options) +0x0a0 CloseIrp : <anonymous-tag> // 仅当 MajorFunction == IRP_MJ_CLOSE 时有效 +0x0c0 OperationTimestamp : _ETW_KERNEL_TRACE_TIMESTAMP // ETW 时间戳,用于性能分析 +0x0e0 TraceStatus : Int4B // ETW 跟踪状态(是否已记录事件) +0x0e8 Data : _FLT_CALLBACK_DATA /*FLTMGR!_FLT_CALLBACK_DATA; Minifilter 回调中传入的 PFLT_CALLBACK_DATA,封装了 I/O 信息 +0x000 Flags : Uint4B +0x008 Thread : Ptr64 _KTHREAD +0x010 Iopb : Ptr64 _FLT_IO_PARAMETER_BLOCK // 参数块 +0x018 IoStatus : _IO_STATUS_BLOCK // 返回状态 +0x028 TagData : Ptr64 _FLT_TAG_DATA_BUFFER // ECP/EFS 相关标签数据 +0x030 QueueLinks : _LIST_ENTRY +0x040 QueueContext : [2] Ptr64 Void +0x030 FilterContext : [4] Ptr64 Void +0x050 RequestorMode : Char */ +0x140 WorkingParameters : _FLT_IO_PARAMETER_BLOCK /*FLTMGR!_FLT_IO_PARAMETER_BLOCK +0x000 IrpFlags : Uint4B +0x004 MajorFunction : UChar +0x005 MinorFunction : UChar +0x006 OperationFlags : UChar +0x007 Reserved : UChar +0x008 TargetFileObject : Ptr64 _FILE_OBJECT +0x010 TargetInstance : Ptr64 _FLT_INSTANCE +0x018 Parameters : _FLT_PARAMETERS // IRP_MJ_xxx */ |
如有错误之处,还望指正。