MiniFilter 架构的解析将从 (1) 初始化阶段的 Frame 初始化与卷抽象-设备栈附加,(2) Filter 注册, (3) Instance 实例化, (4) 回调函数触发等方面进行较为深入、细致的分析。FltpFsNotificationActual 是 fltMgr.sys 在响应文件系统挂载事件时,自动为 Minifilter 创建实例并附加到卷设备栈的核心路径。这是 Minifilter 实现“挂载时自动绑定(Auto-Attach)”机制的底层实现。FltpFsNotificationActual 函数的触发时机如下:
fltMgr 在系统 Phase1 初始化阶段被加载,在完成自身初始化时会遍历当前已注册的所有文件系统,并为每个文件系统设备栈挂载设备对象,创建卷抽象与 frame 进行绑定。KiStartSystemThread -> PspSystemThreadStartup -> Phase1Initialization -> IoInitSystem -> IoInitSystemPreDrivers -> IopInitializeBootDrivers -> IopInitializeBuiltinDriver -> FLTMGR!GsDriverEntry -> FLTMGR!DriverEntry -> FLTMGR!FltpAttachFrame -> FLTMGR!FltpFsNotificationActual -> FLTMGR!FltpAttachToFileSystemDevice -> FLTMGR!FltpAttachDeviceObject -> nt!IoAttachDeviceToDeviceStackSafefilMgr 在初始化阶段,调用函数 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 抽象并将设备对象插入设备栈。(FltpDoFilterNotificationForNewVolume)当一个新卷被挂载时,通知所有已注册的 minifilter,并为每个符合条件的 filter 创建新的实例并附加到该卷设备栈。通过遍历 frame->RegisteredFilters 查找所注册的 filter,调用 FltpEnumerateRegistryInstances 创建 instance 并与 volume 绑定。DriverEntry 中设置 MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] 为 FltpFsControl,包含对文件系统的控制操作,如卷挂载(IRP_MN_MOUNT_VOLUME)。 动态挂载到新卷的设备栈中,函数调用路径如下:nt!IofCallDriver -> FLTMGR!FltpFsControl -> FLTMGR!FltpFsControlMountVolume -> FLTMGR!FltpAttachDeviceObject -> nt!IoAttachDeviceToDeviceStackSafe函数 FltpFsControlMountVolume, nt!IoRegisterFileSystem -> FLTMGR!FltpFsNotification -> FLTMGR!FltpFsNotificationActual -> FLTMGR!FltpAttachToFileSystemDevice -> FLTMGR!FltpAttachDeviceObject -> nt!IoAttachDeviceToDeviceStackSafe函数 FltpFsNotification 的逻辑较为简单,调用 FltpFsNotificationActual 执行设备栈附加。函数 FltRegisterFilter 用于向 MiniFiltter 注册 filter,除了初始化 _FLT_REGISTRATION 结构体中所设置的参数外,还包括:验证 filter 的安全性(FltpInitializeFilterVerifier)、根据注册表所设置的 altitude 按顺序插入 frame->RegisteredFilters 链表。需要注意的是,_FLT_FILTER 结构体的大小会依据所注册回调函数数量而发生拓展。
函数 FltpGetInstanceAltitude 中,读取注册表中实例的键用于获取 Altitude。内部调用 FltpOpenInstancesRegistryKey 打开对应的注册表键,路径为 \\Registry\\Machine\\System\\CurrentControlSet\\Services\\Instance.
查询名为 DEFAULTINSTANCE 的子键,接着查询该子键的 Altitude 值,并返回字符串格式。
这也解释了为什么 MiniFilter 驱动安装时的 INF 文件的重要性。
参见: 有偿求解决,文件过滤驱动函数FltRegisterFilter
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-289723.htm
[原创] MiniFilter架构及其文件过滤原理分析 (update 1/12)
436 浏览
3 回复
学习一下
感谢分享。
这玩意2年前为了分析文件系统, 逆向分析了整个架构,感叹一下,谢谢分享