Minifilter过滤命名管道和邮槽的一些问题

最近有个需求需要监控管道的链接,IRP_MJ_CREATE过滤不到管道的创建和链接。

注册的IRP_MJ_CREATE_NAMED_PIPE这个irp的回调也一直不被调用。

OSR上老外也提了类似的问题:

  • https://community.osr.com/discussion/239743/can-a-minifilter-filter-a-non-file-devices-irps
  • https://community.osr.com/discussion/171174
  • https://community.osr.com/discussion/247489

最后一个OSR上的问题,老外提到了微软的minispy中的部分代码,这个代码是用在注册Filter的时候填写在 FLT_REGISTRATION结构中的flag,这个flag从Win8才开始支持!

在这里插入图片描述
后来也搜到了两篇文章,介绍了Win8的新特性,其中就提到了开始支持过滤命名管道和邮槽,也证明了上面老外提到的这件事。

  • http://fsfilters.blogspot.com/2011/09/whats-new-in-win8-for-file-system.html
  • http://fsfilters.blogspot.com/2014/01/getting-started-with-windows-file_23.html

下面是我写的minifilter代码,用来过滤创建或打开的管道名是wdy就把管道名和当前进程名字打印出来。

代码中注册了下面两个IRP的回调函数:

  • IRP_MJ_CREATE
  • IRP_MJ_CREATE_NAMED_PIPE

最终结果显示,当使用了FLTFL_REGISTRATION_SUPPORT_NPFS_MSFS 这个flag时,

IRP_MJ_CREATE可以监控到打开管道名为wdy的事件
IRP_MJ_CREATE_NAMED_PIPE可以监控到创建管道名为wdy的事件

这个验证结果和《Windows内核原理与实现》书中8.3节介绍的一样
在这里插入图片描述

当不使用FLTFL_REGISTRATION_SUPPORT_NPFS_MSFS属性时,两个IRP都监控不到管道的创建和打开。

微软官方对这个属性的介绍:

  • https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/fltkernel/ns-fltkernel-_flt_registration

在这里插入图片描述

记住,这个属性从Win8才开始支持。

#include <fltKernel.h>
#include <dontuse.h>

#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")


PFLT_FILTER gFilterHandle;
ULONG_PTR OperationStatusCtx = 1;

#define PTDBG_TRACE_ROUTINES            0x00000001
#define PTDBG_TRACE_OPERATION_STATUS    0x00000002

ULONG gTraceFlags = 0;


#define PT_DBG_PRINT( _dbgLevel, _string )          \
    (FlagOn(gTraceFlags,(_dbgLevel)) ?              \
        DbgPrint _string :                          \
        ((int)0))



NTSTATUS FsFilter1Unload(FLT_FILTER_UNLOAD_FLAGS Flags)
{
    UNREFERENCED_PARAMETER(Flags);
    PAGED_CODE();
    PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
        ("FsFilter1!FsFilter1Unload: Entered\n"));

    FltUnregisterFilter(gFilterHandle);

    return STATUS_SUCCESS;
}

extern NTSYSAPI PUCHAR NTAPI PsGetProcessImageFileName(PEPROCESS Process);


/*************************************************************************
    MiniFilter callback routines.
*************************************************************************/
FLT_PREOP_CALLBACK_STATUS PreCreateOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext)
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER(FltObjects);
    UNREFERENCED_PARAMETER(CompletionContext);

    PEPROCESS eProcess = NULL;
    HANDLE pid = PsGetCurrentProcessId();


    do
    {
        if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
        {
            break;
        }

        if ((ULONG)pid == 4 || (ULONG)pid == 0)
        {
            break;
        }

        status = PsLookupProcessByProcessId(pid, &eProcess);
        if (!NT_SUCCESS(status))
        {
            KdPrint(("Get PsLookupProcessByProcessId Failed\n")); break;
        }

        PUCHAR pszProcessName = NULL;
        pszProcessName = PsGetProcessImageFileName(eProcess);
        if (pszProcessName == NULL)
        {
            KdPrint(("Get PsGetProcessImageFileName Failed\n"));  break;
        }

        if (strstr(pszProcessName, "Server.exe") || strstr(pszProcessName, "Client.exe"))
        {
            UNICODE_STRING usPipeName = { 0 };
            FltParseFileName(&FltObjects->FileObject->FileName, NULL, NULL, &usPipeName);

            UNICODE_STRING usTarget = { 0 };
            RtlInitUnicodeString(&usTarget, L"wdy");
            if (RtlEqualUnicodeString(&usTarget, &usPipeName, TRUE))
            {
                DbgPrint("[IRP_MJ_CREATE]=====> Process:%s  Create Named Pipe:%wZ \n", pszProcessName, &usPipeName);
            }

        }
    } while (0);


    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}


FLT_PREOP_CALLBACK_STATUS PreCreateNamedPipeOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext)
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER(FltObjects);
    UNREFERENCED_PARAMETER(CompletionContext);

    PEPROCESS eProcess = NULL;
    HANDLE pid = PsGetCurrentProcessId();


    do
    {
        if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
        {
            break;
        }

        if ((ULONG)pid == 4 || (ULONG)pid == 0)
        {
            break;
        }

        status = PsLookupProcessByProcessId(pid, &eProcess);
        if (!NT_SUCCESS(status))
        {
           break;
        }

        PUCHAR pszProcessName = NULL;
        pszProcessName = PsGetProcessImageFileName(eProcess);
        if (pszProcessName == NULL)
        {
           break;
        }

        if (strstr(pszProcessName, "Server.exe") || strstr(pszProcessName, "Client.exe"))
        {
            UNICODE_STRING usPipeName = { 0 };
            FltParseFileName(&FltObjects->FileObject->FileName, NULL, NULL, &usPipeName);
            
            UNICODE_STRING usTarget = { 0 };
            RtlInitUnicodeString(&usTarget,L"wdy");
            if (RtlEqualUnicodeString(&usTarget, &usPipeName, TRUE))
            {
                DbgPrint("[IRP_MJ_CREATE_NAMED_PIPE]=====> Process:%s  Create Named Pipe:%wZ \n", pszProcessName, &usPipeName);
            }
           
        }
    } while (0);


    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}


//
//  operation registration
//

CONST FLT_OPERATION_REGISTRATION Callbacks[] = 
{
    { 
        IRP_MJ_CREATE,
        0,
        PreCreateOperation,
        NULL
    },
    { 
        IRP_MJ_CREATE_NAMED_PIPE,
        0,
        PreCreateNamedPipeOperation,
        NULL 
    },
    { IRP_MJ_OPERATION_END }
};

//
//  This defines what we want to filter with FltMgr
//

CONST FLT_REGISTRATION FilterRegistration = {
    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    FLTFL_REGISTRATION_SUPPORT_NPFS_MSFS, //  Flags  这里需要做个判断win8才开始支持这个Flag
    NULL,                               //  Context
    Callbacks,                          //  Operation callbacks
    FsFilter1Unload,                    //  MiniFilterUnload

    NULL,//  InstanceSetup
    NULL,//  InstanceQueryTeardown
    NULL,//  InstanceTeardownStart
    NULL,//  InstanceTeardownComplete

    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent
};



/*************************************************************************
    MiniFilter initialization and unload routines.
*************************************************************************/

NTSTATUS DriverEntry ( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath )
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER( RegistryPath );

    PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,("FsFilter1!DriverEntry: Entered\n") );

    status = FltRegisterFilter( DriverObject,&FilterRegistration,&gFilterHandle );

    FLT_ASSERT( NT_SUCCESS( status ) );

    if (NT_SUCCESS( status )) {

        status = FltStartFiltering( gFilterHandle );

        if (!NT_SUCCESS( status )) {

            FltUnregisterFilter( gFilterHandle );
        }
    }

    return status;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值