zoukankan      html  css  js  c++  java
  • Win64 驱动内核编程-17. MINIFILTER(文件保护)

     MINIFILTER(文件保护)

        使用 HOOK 来监控文件操作的方法有很多,可以在 SSDT 上 HOOK 一堆和 FILE 有关的函数,也可以对 FSD 进行 IRP HOOK,不过这些方法既不方便,也不安全。微软推荐的文件操作过滤方法是使用过滤驱动,在 VISTA 之后,推荐使用 MINIFILTER (字面翻译是迷你过滤器)。MINIFILTER 基于标准的文件过滤驱动,但是微软把它封装得很好,使得大家不用注意太多细节,而专注于对 IRP 的过滤。

        之前一直在看一些细节和各种配置文件设置,最后发现如果用VSIDE的话直接就自动生成模板了。先说下创建一个MiniFilter驱动项目:


    然后他会自动生成一个模板文件:


    我们只需要在上面改东西就行了,贼方便。


    编译之后会有两个文件:

    ***.sys 和 ***.inf  inf拷贝到相关虚拟机上右键安装就行了。

    安装之后会生成类似如下注册表:


    OK这样一个基本的MiniFilter驱动就安装上了。

    然后在cmd里对这个驱动的操作和服务是一样的(但是注意这个不是服务,在服务里查不到)

    Sc start MyMiniFilter     开始

    Sc stop MyMiniFilter     停止

    Sc Delete MyMiniFilter   删除(删除后记得自己清理system32/drivers**.sys这个文件)


    下面说下这个框架的细节:

    创建这个项目之后,模板已经被自动创建好了,里面也有很多注释。要自己看下,这里就说几点关键:

     

    CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
    { IRP_MJ_WRITE,
    0,
    MinifilterPreOperation,
    MinifilterPostOperation },
    #if 0 // TODO - List all of the requests to filter.
        { IRP_MJ_CREATE,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_CREATE_NAMED_PIPE,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_CLOSE,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_READ,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_QUERY_INFORMATION,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_SET_INFORMATION,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_QUERY_EA,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_SET_EA,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_FLUSH_BUFFERS,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_QUERY_VOLUME_INFORMATION,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_SET_VOLUME_INFORMATION,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_DIRECTORY_CONTROL,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_FILE_SYSTEM_CONTROL,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_DEVICE_CONTROL,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_INTERNAL_DEVICE_CONTROL,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_SHUTDOWN,
          0,
          MinifilterPreOperationNoPostOperation,
          NULL },                               //post operations not supported
     
        { IRP_MJ_LOCK_CONTROL,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_CLEANUP,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_CREATE_MAILSLOT,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_QUERY_SECURITY,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_SET_SECURITY,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_QUERY_QUOTA,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
        { IRP_MJ_SET_QUOTA,
          0,
          MinifilterPreOperation,
          MinifilterPostOperation },
     
    .....

        上面的东西就是设置开启哪些回调函数(所有回调函数格式一样),Pre是之前的意思,Post是之后的意思。默认的模板是用的if 0给全都关闭了。我是开启了 写 的权限进行测试:


    回调函数代码如下(保护xxxx.txt文件):

    FLT_PREOP_CALLBACK_STATUS
    MinifilterPreOperation (
        _Inout_ PFLT_CALLBACK_DATA Data,
        _In_ PCFLT_RELATED_OBJECTS FltObjects,
        _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
        )
    {
    UNREFERENCED_PARAMETER(FltObjects);
    UNREFERENCED_PARAMETER(CompletionContext);
    PAGED_CODE();
    {
    PFLT_FILE_NAME_INFORMATION nameInfo;
    //直接获得文件名并检查
    if (NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo)))
    {
    if (NT_SUCCESS(FltParseFileNameInformation(nameInfo)))
    {
    WCHAR pTempBuf[512] = { 0 };
    WCHAR *pNonPageBuf = NULL, *pTemp = pTempBuf;
    if (nameInfo->Name.MaximumLength > 512)
    {
    pNonPageBuf = ExAllocatePool(NonPagedPool, nameInfo->Name.MaximumLength);
    pTemp = pNonPageBuf;
    }
    RtlCopyMemory(pTemp, nameInfo->Name.Buffer, nameInfo->Name.MaximumLength);
    DbgPrint("[MiniFilter][IRP_MJ_WRITE]%wZ", &nameInfo->Name);
    _wcsupr(pTemp);
    if (NULL != wcsstr(pTemp, L"xxxx.txt"))  /
    {
    if (NULL != pNonPageBuf)
    ExFreePool(pNonPageBuf);
    FltReleaseFileNameInformation(nameInfo);
    return FLT_PREOP_DISALLOW_FASTIO;
    }
    if (NULL != pNonPageBuf)
    ExFreePool(pNonPageBuf);
    }
    FltReleaseFileNameInformation(nameInfo);
    }
    }
    return FLT_PREOP_SUCCESS_NO_CALLBACK;}
    执行效果如下:

     

     

     

  • 相关阅读:
    Java开发系列-电子邮箱
    Java开发系列-文件上传
    iOS开发系列-常见离线存储方式
    Java开发系列-注解
    Java开发系列-JSP
    Java开发系列-Cookie与Session会话技术
    Java开发系列-JDBC
    Java开发系列-MySQL
    Java开发系列-时间转换
    java开发系列-服务器tomcat
  • 原文地址:https://www.cnblogs.com/csnd/p/12062011.html
Copyright © 2011-2022 走看看