You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mini-Filter拦截JPG失效:无法阻止「Windows照片」打开图片求助

解决方案:Mini-Filter拦截Windows照片应用JPG打开失效问题

我之前碰到过一模一样的问题,Windows照片这个UWP应用的文件访问逻辑确实有点绕,咱们来一步步拆解原因和解决办法:

核心原因分析

你提到PostOperationCallback已经被调用,但拦截失效,主要有几个关键点:

  1. 拦截时机太晚:PostCreate阶段调用FltCancelFileOpen时,文件句柄已经被应用(或其代理进程)成功获取,此时取消操作已经无法阻止应用读取文件。
  2. UWP应用的代理访问:Windows照片是UWP应用,它的文件操作并非直接发起,而是通过系统Broker进程(比如FileBroker.exe)代理执行,你的拦截逻辑可能没处理这种间接请求。
  3. 快速IO绕过:Windows照片可能使用快速IO(Fast IO)路径读取文件,而你的驱动只注册了常规MJ_CREATE回调,没覆盖快速IO场景。

具体解决方案

1. 把拦截逻辑移到PreCreate回调(最可靠的方式)

在文件打开操作的PreCreate阶段直接拒绝请求,这是阻止文件被打开的最佳时机,因为此时系统还没完成文件句柄的创建。示例代码如下:

FLT_PREOP_CALLBACK_STATUS PreCreateCallback(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Out_ PVOID *CompletionContext
)
{
    UNREFERENCED_PARAMETER(CompletionContext);

    PFLT_FILE_NAME_INFORMATION fileNameInfo = NULL;
    NTSTATUS status = FltGetFileNameInformation(
        Data, 
        FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, 
        &fileNameInfo
    );

    if (NT_SUCCESS(status)) {
        UNICODE_STRING jpgExt;
        RtlInitUnicodeString(&jpgExt, L".JPG");
        // 忽略大小写匹配扩展名
        if (RtlCompareUnicodeString(&fileNameInfo->Extension, &jpgExt, TRUE) == 0) {
            DbgPrint("Blocking JPG file access in PreCreate...\n");
            // 直接返回访问拒绝错误
            Data->IoStatus.Status = STATUS_ACCESS_DENIED;
            Data->IoStatus.Information = 0;
            FltReleaseFileNameInformation(fileNameInfo);
            return FLT_PREOP_COMPLETE;
        }
        FltReleaseFileNameInformation(fileNameInfo);
    }

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

2. 处理UWP Broker进程的代理请求

Windows照片的文件操作会通过Broker进程发起,你需要在回调中验证请求的发起进程,确保拦截这些代理请求:

  • 使用FltGetRequestorProcessId获取请求进程ID
  • 通过PsLookupProcessByProcessId获取进程对象,再查询进程名称(比如检查是否是FileBroker.exe或explorer.exe)
  • 结合令牌信息(SeQueryInformationToken)判断是否属于UWP沙箱环境,针对性拦截

3. 注册快速IO回调防止绕过

Windows照片可能使用快速IO路径读取文件,你的驱动需要注册对应的快速IO回调(比如FastIoRead、FastIoQueryBasicInfo),在这些回调中同样检查文件扩展名并拒绝操作。

4. 优化PostCreate阶段的拦截逻辑(如果必须用PostCreate)

如果因为某些原因必须在PostCreate阶段处理,需要确保不仅调用FltCancelFileOpen,还要主动关闭文件句柄并设置错误状态:

FLT_POSTOP_CALLBACK_STATUS PostCreateCallback(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _In_opt_ PVOID CompletionContext,
    _In_ FLT_POST_OPERATION_FLAGS Flags
)
{
    UNREFERENCED_PARAMETER(CompletionContext);
    UNREFERENCED_PARAMETER(Flags);

    if (Data->IoStatus.Status == STATUS_SUCCESS) {
        PFLT_FILE_NAME_INFORMATION fileNameInfo = NULL;
        NTSTATUS status = FltGetFileNameInformation(
            Data, 
            FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, 
            &fileNameInfo
        );

        if (NT_SUCCESS(status)) {
            UNICODE_STRING jpgExt;
            RtlInitUnicodeString(&jpgExt, L".JPG");
            if (RtlCompareUnicodeString(&fileNameInfo->Extension, &jpgExt, TRUE) == 0) {
                DbgPrint("Canceling JPG file open in PostCreate...\n");
                // 取消打开操作
                FltCancelFileOpen(FltObjects->Instance, Data);
                // 主动关闭文件句柄,确保应用无法使用
                FltClose(FltObjects->FileObject);
                // 设置错误状态
                Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                Data->IoStatus.Information = 0;
            }
            FltReleaseFileNameInformation(fileNameInfo);
        }
    }

    return FLT_POSTOP_FINISHED_PROCESSING;
}

额外注意事项

  • 确保你的驱动有足够的权限:UWP应用运行在沙箱中,驱动需要具备SeSecurityPrivilege等权限才能正确拦截其请求。
  • 测试不同的JPG文件场景:比如网络共享中的JPG、本地磁盘的JPG,确保拦截逻辑覆盖所有场景。

内容的提问来源于stack exchange,提问作者Bryce Woods

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:04:30