zoukankan      html  css  js  c++  java
  • Win64 驱动内核编程-34.对抗与枚举MiniFilter

    对抗与枚举MiniFilter

        MiniFilter 是目前杀毒软件用来实现“文件系统自我保护”和“文件实时监控”的方法。

    由于 MiniFilter 模型简单,开发快捷,通用性好,以前用 FSD HOOK 或者标准过滤驱动来实现相关功能的杀软纷纷改用 MiniFilter,比如卡巴斯基。不过,枚举 MiniFilter 就跟之前枚举回调的方法不太相同了,因为 MiniFilter 的框架不在 NTOSKRNL 里,自成一套系统,有专用的 API。不过“自成一套系统,有专用 API”的好处就是,无需我们自己通过特征码来定位数组或者链表,直接使用 MiniFilter 提供的 API 就行。

        枚举MiniFilter主要使用FltEnumerateFilters这个API,它会返回过滤器对象(FLT_FILTER)的地址,然后根据过滤器对象的地址,加上一个偏移,获得记录过滤器 PreCall、PostCall、IRP 等信息的结构体指针(PFLT_OPERATION_REGISTRATION)。上文之所以说要加上偏移,是因为 FLT_FILTER 的定义在每个系统都不同,比如 WIN7X64 中的定义为:

    nt!DbgBreakPointWithStatus:

    fffff800`03e74f60 cc              int     3

    kd> dt fltmgr!_FLT_FILTER

       +0x000 Base             : _FLT_OBJECT

       +0x020 Frame            : Ptr64 _FLTP_FRAME

       +0x028 Name             : _UNICODE_STRING

       +0x038 DefaultAltitude  : _UNICODE_STRING

       +0x048 Flags            : _FLT_FILTER_FLAGS

       +0x050 DriverObject     : Ptr64 _DRIVER_OBJECT

       +0x058 InstanceList     : _FLT_RESOURCE_LIST_HEAD

       +0x0d8 VerifierExtension : Ptr64 _FLT_VERIFIER_EXTENSION

       +0x0e0 VerifiedFiltersLink : _LIST_ENTRY

       +0x0f0 FilterUnload     : Ptr64     long 

       +0x0f8 InstanceSetup    : Ptr64     long 

       +0x100 InstanceQueryTeardown : Ptr64     long 

       +0x108 InstanceTeardownStart : Ptr64     void 

       +0x110 InstanceTeardownComplete : Ptr64     void 

       +0x118 SupportedContextsListHead : Ptr64 _ALLOCATE_CONTEXT_HEADER

       +0x120 SupportedContexts : [6] Ptr64 _ALLOCATE_CONTEXT_HEADER

       +0x150 PreVolumeMount   : Ptr64     _FLT_PREOP_CALLBACK_STATUS 

       +0x158 PostVolumeMount  : Ptr64     _FLT_POSTOP_CALLBACK_STATUS 

       +0x160 GenerateFileName : Ptr64     long 

       +0x168 NormalizeNameComponent : Ptr64     long 

       +0x170 NormalizeNameComponentEx : Ptr64     long 

       +0x178 NormalizeContextCleanup : Ptr64     void 

       +0x180 KtmNotification  : Ptr64     long 

       +0x188 Operations       : Ptr64 _FLT_OPERATION_REGISTRATION

       +0x190 OldDriverUnload  : Ptr64     void 

       +0x198 ActiveOpens      : _FLT_MUTEX_LIST_HEAD

       +0x1e8 ConnectionList   : _FLT_MUTEX_LIST_HEAD

       +0x238 PortList         : _FLT_MUTEX_LIST_HEAD

       +0x288 PortLock         : _EX_PUSH_LOCK

     FLT_OPERATION_REGISTRATION 的结构体定义是不变的:

     枚举代码如下:

    #include <Fltkernel.h>
    ULONG FltFilterOperationsOffset=0x188; //WIN7 OFFSET of fltmgr!_FLT_FILTER->PFLT_OPERATION_REGISTRATION
     
    //typedef struct _FLT_OPERATION_REGISTRATION
    //{
    //UCHARMajorFunction;
    //ULONGFlags;
    //PVOIDPreOperation;
    //PVOIDPostOperation;
    //PVOIDReserved1;
    //} FLT_OPERATION_REGISTRATION, *PFLT_OPERATION_REGISTRATION;
     
    typedef struct _FLT_FILTER
    {
    UCHAR buffer[1024];
    } FLT_FILTER, *PFLT_FILTER;
     
    //NTSTATUS
    //__fastcall
    //FltEnumerateFilters
    //(
    //    PFLT_FILTER *FilterList,
    //    ULONG FilterListSize,
    //    PULONG NumberFiltersReturned
    //);
    //
    //NTSTATUS
    //__fastcall
    //FltObjectDereference
    //(
    //    PVOID FltObject
    //);
     
    ULONG EnumMiniFilter()
    {
    long	ntStatus;
    ULONG	uNumber;
    PVOID	pBuffer = NULL;
    ULONG	uIndex = 0, DrvCount = 0;
    PVOID	pCallBacks  = NULL, pFilter = NULL;
    PFLT_OPERATION_REGISTRATION pNode;
    do
    {
    if(pBuffer != NULL)
    {
    ExFreePool(pBuffer);
    pBuffer = NULL;
    }
    ntStatus = FltEnumerateFilters(NULL,  0, &uNumber);
    if(ntStatus != STATUS_BUFFER_TOO_SMALL)
    break;
    pBuffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(PFLT_FILTER) * uNumber, 'mnft');
    if(pBuffer == NULL)
    {
    ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    break;
    }
    ntStatus = FltEnumerateFilters(pBuffer, uNumber, &uNumber);
    }
    while (ntStatus == STATUS_BUFFER_TOO_SMALL);
    if(! NT_SUCCESS(ntStatus))
    {
    if(pBuffer != NULL)
    ExFreePool(pBuffer);
    return 0;
    }
    DbgPrint("MiniFilter Count: %ld
    ",uNumber);
    DbgPrint("------
    ");
    __try
    {
    while(DrvCount<uNumber)
    {
    pFilter = (PVOID)(*(PULONG64)((PUCHAR)pBuffer + DrvCount * 8));
    pCallBacks = (PVOID)((PUCHAR)pFilter + FltFilterOperationsOffset);
    pNode = (PFLT_OPERATION_REGISTRATION)(*(PULONG64)pCallBacks);
    __try
    {
    while(pNode->MajorFunction != 0x80)	//IRP_MJ_OPERATION_END
    {
    if(pNode->MajorFunction<28)	//MajorFunction id is 0~27
    {
    DbgPrint("Object=%p	PreFunc=%p	PostFunc=%p	IRP=%d
    ",
    pFilter,
    pNode->PreOperation,
    pNode->PostOperation,
    pNode->MajorFunction);
    }
    pNode++;
    }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    FltObjectDereference(pFilter);
    DbgPrint("[EnumMiniFilter]EXCEPTION_EXECUTE_HANDLER: pNode->MajorFunction
    ");
    ntStatus = GetExceptionCode();
    ExFreePool(pBuffer);
    return uIndex;
    }
    DrvCount++;
    FltObjectDereference(pFilter);
    DbgPrint("------
    ");
    }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    FltObjectDereference(pFilter);
    DbgPrint("[EnumMiniFilter]EXCEPTION_EXECUTE_HANDLER
    ");
    ntStatus = GetExceptionCode();
    ExFreePool(pBuffer);
    return uIndex;
    }
    if(pBuffer != NULL)
    {
    ExFreePool(pBuffer);
    ntStatus=STATUS_SUCCESS;
    }
    return uIndex;}

    执行结果:

    不过对抗 MiniFilter 似乎就只有两种方法了:

    1.把记录的函数地址改为自己设置的空函数;

    2.把处理函数头改为 RET 直接返回。 为什么不能把 直接把 MiniFilter  对象 反注册呢?因为MSDN 对 对 FltUnregisterFilter  的 用途 给出了 这样的解释 :A minifilter driver can only callFltUnregisterFilter to unregister itself, not another minifilter driver。据我测试,如果第三方驱动强制使用此函数注销一个 MiniFilter,轻则无效,重则蓝屏。

    把 MINIFILTER 的处理函数禁用掉之后,卡巴斯基 2013 在 WIN64 系统上的文件保护就彻底失效了,可以直接使用最简单的方法来删除卡巴斯基文件夹内的文件,国内那些采用同样方法实现文件自我保护的杀毒软件(****)同理。

    宋孖健,13

  • 相关阅读:
    关于二进制的利用
    2017年浙江中医药大学程序设计竞赛 Solution
    2018-2019 ACM-ICPC, Asia Xuzhou Regional Contest Solution
    2018-2019 ACM-ICPC, Asia Shenyang Regional Contest Solution
    2018-2019 ACM-ICPC, Asia Nanjing Regional Contest Solution
    AtCoder Grand Contest 029 Solution
    BZOJ 3307: 雨天的尾巴
    Codeforces Round #526 (Div. 2) Solution
    2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution
    [HZNUOJ] 博
  • 原文地址:https://www.cnblogs.com/csnd/p/12061976.html
Copyright © 2011-2022 走看看