首页
社区
课程
招聘
[原创] MiniFilter架构及其文件过滤原理分析 (update 1/12)
发表于: 3天前 520

[原创] 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 抽象并将设备对象插入设备栈。

  1. 调用 IoGetDeviceAttachmentBaseRef 获取当前设备栈栈底的设备对象,调用 IoEnumerateDeviceObjectList 枚举设备对象列表。
  2. 遍历设备对象列表,调用 IoGetDiskDeviceObject 获取对应顶层磁盘设备对象指针。调用 FltpCreateVolumeDeviceObject+FltpAttachDeviceObject 为每个磁盘设备对象创建并绑定 volume。
  3. 有条件(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

  1. 调用 FltpLogEventWithObjectID 关联 volume-frame-device,设置 _IRP_CTRL。
  2. 调用 FltpPerformPreMountCallbacks 执行卷挂载的前置回调函数。
  3. 为向下传递的 IRP(MountVolume 请求)准备下一层 _IO_STACK_LOCATION,复制必要的参数,并注册一个在任何情况下都会被调用的完成例程(FltpFsControlCompletion),以便过滤管理器能在底层文件系统处理完挂载请求后进行后续处理。

图片描述

  1. 调用 FltpAttachDeviceObject 将设备对象插入设备栈。
  2. 调用 FltpPerformPostMountCallbacks 执行卷挂载的后置回调函数。
  3. 调用 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。

  1. 内部调用 FltpOpenInstancesRegistryKey 打开对应的注册表键,路径为 \\Registry\\Machine\\System\\CurrentControlSet\\Services\\Instance.
    图片描述

  2. 查询名为 DEFAULTINSTANCE 的子键,接着查询该子键的 Altitude 值,并返回字符串格式。
    图片描述
    图片描述

这也解释了为什么 MiniFilter 驱动安装时的 INF 文件的重要性。
参见: 有偿求解决,文件过滤驱动函数FltRegisterFilter调用失败返回0xc0000034的问题

2.2 FltpFindFrameForFilter

  1. 当 flttMgr 中还未创建 frame 时,调用函数 FltpAttachFrame 设置并初始化 frame,填充 altitude,完成设备栈的插入。frame->AltitudeIntervalLow 默认为0,frame->AltitudeIntervalHigh 为当前 altitude。
    图片描述
  2. 当 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中:

  1. 函数 FltpNumCallbackNodes 获取当前 filter 的有效回调数。由于 filter 所注册的回调函数数量不固定,因此申请 _FLT_INSTANCE 结构体的内存时需要获取有效回调函数数量。fiilter->Operations 实际上指向一个 _FLT_OPERATION_REGISTRATION 数组,以 0x80 为结束标志。类似的,instance->CallbackNodes 提供了一个长度为 50 的 _CALLBACK_NODE 指针表用于快速索引,而 _CALLBACK_NODE 结构体紧随 instance。
    图片描述

  2. 函数 FltpDoInstanceSetupNotification 调用 filter->InstanceSetup 执行回调函数。

  3. 函数 FltpSetCallbacksForInstance 设置回调函数组。

  4. 按照 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                 

函数 FltpPassThroughInternalFltpLegacyProcessingAfterPreCallbacksCompleted 内部调用 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
       */

如有错误之处,还望指正。


传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 1天前 被ALwalker编辑 ,原因: 补充内容
收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 2790
活跃值: (5597)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
学习一下
1天前
0
游客
登录 | 注册 方可回帖
返回