Windows驱动编程之文件过滤
字数 1480 2025-08-23 18:31:18

Windows驱动编程之文件过滤技术详解

1. Minifilter框架概述

Minifilter(Mini-filter Installable File System)是微软官方推荐的文件过滤框架,具有以下优势:

  • 良好的兼容性和高封装接口
  • 加快开发周期,降低开发难度
  • 解决早期版本驱动兼容性问题
  • 统一接口规范,减少对系统的不确定因素

1.1 工作流程

用户I/O请求的处理流程:

  1. I/O请求转发到文件系统
  2. 过滤管理拦截请求并按顺序调用已注册的微型过滤器
  3. 文件系统驱动程序处理并转发修改后的请求
  4. 存储驱动程序堆栈准备硬件请求

2. Minifilter框架实现

2.1 基本结构

Minifilter主要包含四部分:注册、启动、预操作、后操作。

CONST FLT_REGISTRATION FilterRegistration = {
    sizeof(FLT_REGISTRATION),  // Size
    FLT_REGISTRATION_VERSION,  // Version
    0,                         // Flags
    NULL,                      // Context
    Callbacks,                 // Operation callbacks
    NULL,                      // MiniFilterUnload
    FsFilter1InstanceSetup,    // InstanceSetup
    FsFilter1InstanceQueryTeardown,  // InstanceQueryTeardown
    FsFilter1InstanceTeardownStart,  // InstanceTeardownStart
    FsFilter1InstanceTeardownComplete, // InstanceTeardownComplete
    NULL,                      // GenerateFileName
    NULL,                      // GenerateDestinationFileName
    NULL                       // NormalizeNameComponent
};

NTSTATUS status;
status = FltRegisterFilter(
    DriverObject,              //Driver
    &FilterRegistration,       //Registration
    &MiniSpyData.FilterHandle  //RetFilter
);

2.2 操作注册结构

FLT_OPERATION_REGISTRATION是关键结构:

typedef struct _FLT_OPERATION_REGISTRATION {
    UCHAR MajorFunction;
    FLT_OPERATION_REGISTRATION_FLAGS Flags;
    PFLT_PRE_OPERATION_CALLBACK PreOperation;
    PFLT_POST_OPERATION_CALLBACK PostOperation;
    PVOID Reserved1;
} FLT_OPERATION_REGISTRATION, *PFLT_OPERATION_REGISTRATION;

参数说明:

  1. MajorFunction - 拦截的操作类型:

    • IRP_MJ_CLEANUP
    • IRP_MJ_CLOSE
    • IRP_MJ_CREATE
    • IRP_MJ_DEVICE_CONTROL
    • IRP_MJ_FILE_SYSTEM_CONTROL
    • IRP_MJ_FLUSH_BUFFERS
    • IRP_MJ_INTERNAL_DEVICE_CONTROL
    • IRP_MJ_PNP
    • IRP_MJ_POWER
    • IRP_MJ_QUERY_INFORMATION
    • IRP_MJ_READ
    • IRP_MJ_SET_INFORMATION
    • IRP_MJ_SHUTDOWN
    • IRP_MJ_SYSTEM_CONTROL
    • IRP_MJ_WRITE
  2. Flags - 过滤选项:

    • SKIP_CACHED_IO:不过滤缓冲区读写
    • SKIP_PAGING_IO:不过滤分页读写
    • SKIP_NON_DASD_IO:仅对读写回调有用
  3. PreOperation - 预操作回调函数

  4. PostOperation - 后操作回调函数

3. Minifilter IPC通信

3.1 内核层(R0)实现

// 绑定安全描述符
FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);

// 初始化属性对象
RtlSetDaclSecurityDescriptor(sd, TRUE, NULL, FALSE);
RtlInitUnicodeString(&EventPortName, L"\\HadesEventFltPort");
InitializeObjectAttributes(
    &oa,
    &EventPortName,
    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
    NULL,
    sd
);

// 创建通信端口
status = FltCreateCommunicationPort(
    g_FltServerPortEvnet,
    &g_FltServerPortEvnetPort,
    &oa,
    NULL,
    CommunicateConnect,
    CommunicateDisconnect,
    NULL,
    1
);

3.2 用户层(R3)实现

// 连接驱动创建的Port
Status = FilterConnectCommunicationPort(
    L"\\HadesEventFltPort",  // Driver CreatePortName
    0,
    NULL,
    0,
    NULL,
    &g_hPort
);

if (Status == HRESULT_FROM_WIN32(S_OK)) {
    // 绑定IOCP端口(异步接收)
    g_comPletion = CreateIoCompletionPort(g_hPort, NULL, 0, 4);
    if (nullptr == g_comPletion) {
        CloseHandle(g_hPort);
        g_hPort = nullptr;
        continue;
    }
    
    // 获取消息分发处理
    Status = FilterGetMessage(
        g_hPort,
        &msg->MessageHeader,
        FIELD_OFFSET(COMMAND_MESSAGE, Overlapped),
        &msg->Overlapped
    );
}

4. 文件/目录保护技术

4.1 基本拦截方法

注册IRP_MJ_CREATE和IRP_MJ_SET_INFORMATION回调:

{ IRP_MJ_CREATE, 0, FsFilter1PreOperation, NULL },
{ IRP_MJ_SET_INFORMATION, 0, FsFilter1PreOperation, NULL }

4.2 关键信息获取

  1. 获取IRP类型
const unsigned char IRP_MJ_CODE = Data->Iopb->MajorFunction;
  1. 获取进程PID
const DWORD dwPID = (DWORD)PsGetCurrentProcessId();
  1. 获取文件路径
PFLT_FILE_NAME_INFORMATION pNameInfo = NULL;
NTSTATUS status = FltGetFileNameInformation(
    Data, 
    FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, 
    &pNameInfo
);
  1. 文件操作类型判断
Data->Iopb->Parameters.SetFileInformation.FileInformationClass;

// 重命名
case FileRenameInformation:
// 删除
case FileDispositionInformation:

4.3 访问控制

  1. 拒绝访问
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
return FLT_PREOP_COMPLETE;
  1. 允许访问
return FLT_PREOP_SUCCESS_NO_CALLBACK;
  1. 创建操作权限判断
if (((Data->Iopb->Parameters.Create.Options >> 24) & 0x000000ff) == FILE_CREATE || 
    ((Data->Iopb->Parameters.Create.Options >> 24) & 0x000000ff) == FILE_OPEN_IF || 
    ((Data->Iopb->Parameters.Create.Options >> 24) & 0x000000ff) == FILE_OVERWRITE_IF)
{
    // 处理创建/打开操作
}

5. 文件隐藏技术

5.1 注册目录控制回调

{ IRP_MJ_DIRECTORY_CONTROL, 0, FsFilterAntsDrPostFileHide, NULL }

5.2 实现细节

  1. 判断查询操作
if (Data->Iopb->MinorFunction == IRP_MN_QUERY_DIRECTORY && 
    (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass == FileBothDirectoryInformation) && 
    Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length > 0 && 
    NT_SUCCESS(Data->IoStatus.Status))
{
    // 处理目录查询
}
  1. 获取缓冲区
if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL) {
    Bufferptr = MmGetSystemAddressForMdl(
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress, 
        NormalPagePriority
    );
} else {
    Bufferptr = Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;
}
  1. 修改目录信息
PFILE_BOTH_DIR_INFORMATION pCutFileInfo = (PFILE_BOTH_DIR_INFORMATION)Bufferptr;
PFILE_BOTH_DIR_INFORMATION pPreFileInfo = pCutFileInfo;
PFILE_BOTH_DIR_INFORMATION pNextFileInfo = 0;
ULONG uNextOffset = 0;

// 找到要隐藏的文件名并修改链表结构
if (uNextOffset == 0)
    pPreFileInfo->NextEntryOffset = 0;
else
    pPreFileInfo->NextEntryOffset = (ULONG)((PCHAR)pCutFileInfo - (PCHAR)pPreFileInfo + uNextOffset);

pCutFileInfo = pNextFileInfo;

6. 进程/模块拦截技术

6.1 进程拦截

  1. 使用PsSetCreateProcessNotifyRoutineEx
PsSetCreateProcessNotifyRoutineEx(
    (PCREATE_PROCESS_NOTIFY_ROUTINE_EX)Process_NotifyProcessEx, 
    FALSE
);
  1. 使用ObRegisterCallbacks
NTSTATUS status = ObRegisterCallbacks(&obReg, &g_handleobj);
  1. 卸载回调
PsSetCreateProcessNotifyRoutineEx(
    (PCREATE_PROCESS_NOTIFY_ROUTINE_EX)Process_NotifyProcessEx, 
    TRUE
);
ObUnRegisterCallbacks(g_handleobj);

6.2 DLL模块拦截

  1. 注册IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
{ IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION, 0, FsFilterAntsDrvPreExe, NULL }
  1. 判断执行状态
if (Data->Iopb->Parameters.AcquireForSectionSynchronization.PageProtection == PAGE_EXECUTE) {
    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
  1. 拦截方法
Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; // 弹出资源错误窗口
// 或
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->Iostatus.information = 0;
return FLT_PREOP_COMPLETE;
  1. PE文件验证
// 通过FltReadFile读取FileObject对象,解析PE头验证是否为有效EXE/DLL

7. 总结

本文详细介绍了Windows文件过滤驱动的开发技术,重点包括:

  1. Minifilter框架的基本原理和实现方法
  2. 内核与用户态的通信机制
  3. 文件/目录的保护技术
  4. 文件隐藏的实现方法
  5. 进程和模块拦截技术

这些技术在安全EDR/DLP、游戏反作弊、云存储等场景中有广泛应用。开发者应根据实际需求选择合适的拦截点和实现方式,同时注意性能和稳定性问题。

Windows驱动编程之文件过滤技术详解 1. Minifilter框架概述 Minifilter(Mini-filter Installable File System)是微软官方推荐的文件过滤框架,具有以下优势: 良好的兼容性和高封装接口 加快开发周期,降低开发难度 解决早期版本驱动兼容性问题 统一接口规范,减少对系统的不确定因素 1.1 工作流程 用户I/O请求的处理流程: I/O请求转发到文件系统 过滤管理拦截请求并按顺序调用已注册的微型过滤器 文件系统驱动程序处理并转发修改后的请求 存储驱动程序堆栈准备硬件请求 2. Minifilter框架实现 2.1 基本结构 Minifilter主要包含四部分:注册、启动、预操作、后操作。 2.2 操作注册结构 FLT_OPERATION_REGISTRATION 是关键结构: 参数说明: MajorFunction - 拦截的操作类型: IRP_ MJ_ CLEANUP IRP_ MJ_ CLOSE IRP_ MJ_ CREATE IRP_ MJ_ DEVICE_ CONTROL IRP_ MJ_ FILE_ SYSTEM_ CONTROL IRP_ MJ_ FLUSH_ BUFFERS IRP_ MJ_ INTERNAL_ DEVICE_ CONTROL IRP_ MJ_ PNP IRP_ MJ_ POWER IRP_ MJ_ QUERY_ INFORMATION IRP_ MJ_ READ IRP_ MJ_ SET_ INFORMATION IRP_ MJ_ SHUTDOWN IRP_ MJ_ SYSTEM_ CONTROL IRP_ MJ_ WRITE Flags - 过滤选项: SKIP_ CACHED_ IO:不过滤缓冲区读写 SKIP_ PAGING_ IO:不过滤分页读写 SKIP_ NON_ DASD_ IO:仅对读写回调有用 PreOperation - 预操作回调函数 PostOperation - 后操作回调函数 3. Minifilter IPC通信 3.1 内核层(R0)实现 3.2 用户层(R3)实现 4. 文件/目录保护技术 4.1 基本拦截方法 注册IRP_ MJ_ CREATE和IRP_ MJ_ SET_ INFORMATION回调: 4.2 关键信息获取 获取IRP类型 : 获取进程PID : 获取文件路径 : 文件操作类型判断 : 4.3 访问控制 拒绝访问 : 允许访问 : 创建操作权限判断 : 5. 文件隐藏技术 5.1 注册目录控制回调 5.2 实现细节 判断查询操作 : 获取缓冲区 : 修改目录信息 : 6. 进程/模块拦截技术 6.1 进程拦截 使用PsSetCreateProcessNotifyRoutineEx : 使用ObRegisterCallbacks : 卸载回调 : 6.2 DLL模块拦截 注册IRP_ MJ_ ACQUIRE_ FOR_ SECTION_ SYNCHRONIZATION : 判断执行状态 : 拦截方法 : PE文件验证 : 7. 总结 本文详细介绍了Windows文件过滤驱动的开发技术,重点包括: Minifilter框架的基本原理和实现方法 内核与用户态的通信机制 文件/目录的保护技术 文件隐藏的实现方法 进程和模块拦截技术 这些技术在安全EDR/DLP、游戏反作弊、云存储等场景中有广泛应用。开发者应根据实际需求选择合适的拦截点和实现方式,同时注意性能和稳定性问题。