Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

minifilter callbacks routines sometimes not calling

johnhouldingjohnhoulding Member Posts: 28
edited January 13 in NTFSD

I have minifilter which intercept create or rename operation (only for exe file). So I have these callback routines. PreCreate + PostCreate, PreWrite, PreCleanup + PostCleanup.
in postcreate i create stream handle context for newly created exe file and copy filename to context. in PreWrite if NT_SUCCESS(FltGetStreamHandleContext) I set context->rescan = TRUE and return FLT_PREOP_SUCCESS_WITH_CALLBACK. Then in PreCleanup if NT_SUCCESS(FltGetStreamHandleContext) I return FLT_PREOP_SYNCHRONIZE. And in postCleanup i send filename to user mode app with FltSendMessage .Actually it works but sometimes I didnt see filename in my usermode app. İt occur randomly and it also occur IRP_MJ_SET_INFORMATION PreSetInformation. In my usermode app with FltGetMessage i get filename and open this file then read and close + call Sleep(2000) for testing. When I create new exe file and during usermode Sleep(2000) rename other file I didnt see renamed filename and vice versa.

I put my source code here maybe someone help me?

FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{
    UNREFERENCED_PARAMETER(FltObjects);
    UNREFERENCED_PARAMETER(CompletionContext = NULL);



    if (IoThreadToProcess(Data->Thread) == ScannerData.UserProcess) {


        return FLT_PREOP_SUCCESS_NO_CALLBACK;
    }

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}



FLT_POSTOP_CALLBACK_STATUS ScannerPostOpCreate(PFLT_CALLBACK_DATA Data,
    PCFLT_RELATED_OBJECTS FltObjects,
    PVOID CompletionContext,
    FLT_POST_OPERATION_FLAGS Flags)
{

    PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
    POBJECT_NAME_INFORMATION name = NULL;
    NTSTATUS status;
    PSCANNER_NOTIFICATION notification = NULL;
    ULONG replyLen = 0;
    UNICODE_STRING extension = RTL_CONSTANT_STRING(L"exe");
    PSCANNER_CONTEXT scannerContext = NULL;



    if (!NT_SUCCESS(Data->IoStatus.Status) ||
        (STATUS_REPARSE == Data->IoStatus.Status)) {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }


    if (ScannerData.ClientPort == NULL)
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }

    status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);
    if (!NT_SUCCESS(status))
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }


    status = FltParseFileNameInformation(FileNameInfo);
    if (!NT_SUCCESS(status))
    {
        FltReleaseFileNameInformation(FileNameInfo);
        return FLT_POSTOP_FINISHED_PROCESSING;
    }

    if (FileNameInfo->Extension.Length == 0)
    {
        FltReleaseFileNameInformation(FileNameInfo);
        return FLT_POSTOP_FINISHED_PROCESSING;
    }


    if (RtlCompareUnicodeString(&extension, &FileNameInfo->Extension, TRUE) != 0)
    {
        FltReleaseFileNameInformation(FileNameInfo);
        return FLT_POSTOP_FINISHED_PROCESSING;
    }

    FltReleaseFileNameInformation(FileNameInfo);

    if (FltObjects->FileObject->WriteAccess)
    {

        status = IoQueryFileDosDeviceName(FltObjects->FileObject, &name);
        if (NT_SUCCESS(status))
        {

            status = FltAllocateContext(ScannerData.Filter,
                FLT_STREAMHANDLE_CONTEXT,
                sizeof(SCANNER_CONTEXT),
                NonPagedPool,
                &scannerContext);

            if (NT_SUCCESS(status))
            {
                RtlCopyMemory(scannerContext->Path, name->Name.Buffer, name->Name.MaximumLength);
                scannerContext->Len = name->Name.MaximumLength;
                scannerContext->Rescan = FALSE;

                status = FltSetStreamHandleContext(FltObjects->Instance,
                    FltObjects->FileObject,
                    FLT_SET_CONTEXT_REPLACE_IF_EXISTS,
                    scannerContext,
                    NULL);

                if (!NT_SUCCESS(status))
                {
                    DbgPrint("Error set setram context");
                    FltReleaseContext(scannerContext);
                    ExFreePool(name);
                    return FLT_POSTOP_FINISHED_PROCESSING;
                }

                DbgPrint("Context yaradildi\n");


                FltReleaseContext(scannerContext);

            }
            else {
                DbgPrint("Cant allocate memory\n");
            }



            ExFreePool(name);
        }

    }

    return FLT_POSTOP_FINISHED_PROCESSING;
}

FLT_PREOP_CALLBACK_STATUS
ScannerPreWrite(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{

    NTSTATUS status;
    PSCANNER_CONTEXT scannerContext = NULL;
    /*POBJECT_NAME_INFORMATION name = NULL;*/


    status = FltGetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, &scannerContext);
    if (NT_SUCCESS(status))
    {

        if (scannerContext->Rescan == FALSE)
        {
            scannerContext->Rescan = TRUE;

            FltSetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, FLT_SET_CONTEXT_REPLACE_IF_EXISTS, scannerContext, NULL);

            FltReleaseContext(scannerContext);

            return FLT_PREOP_SUCCESS_WITH_CALLBACK;
        }


        FltReleaseContext(scannerContext);

    }

    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}


FLT_PREOP_CALLBACK_STATUS
ScannerPreCleanup(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{
    NTSTATUS status;
    PSCANNER_CONTEXT scannerContext = NULL;

    status = FltGetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, &scannerContext);
    if (!NT_SUCCESS(status))
    {
        return FLT_PREOP_SUCCESS_NO_CALLBACK;
    }



    FltReleaseContext(scannerContext);

    return FLT_PREOP_SYNCHRONIZE;
}





FLT_POSTOP_CALLBACK_STATUS ScannerPostCleanup(PFLT_CALLBACK_DATA Data,
    PCFLT_RELATED_OBJECTS FltObjects,
    PVOID CompletionContext,
    FLT_POST_OPERATION_FLAGS Flags)
{
    NTSTATUS status;
    PSCANNER_CONTEXT scannerContext = NULL;
    PSCANNER_NOTIFICATION notification = NULL;
    ULONG replyLen = 0;


    if (ScannerData.ClientPort == NULL)
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }


    status = FltGetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, &scannerContext);
    if (NT_SUCCESS(status))
    {
        if (scannerContext->Rescan == TRUE)
        {
            notification = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCANNER_NOTIFICATION), 'X66');
            if (notification == NULL)
            {
                FltReleaseContext(scannerContext);
                return FLT_POSTOP_FINISHED_PROCESSING;;
            }

            replyLen = sizeof(SCANNER_REPLY);

            RtlCopyMemory(notification->PathName, scannerContext->Path, scannerContext->Len);

            status = FltSendMessage(ScannerData.Filter,
                &ScannerData.ClientPort,
                notification,
                sizeof(SCANNER_NOTIFICATION),
                notification,
                &replyLen,
                NULL
            );

            if (!NT_SUCCESS(status))
            {
                DbgPrint("Error FltSendMessage\n");
            }

            ExFreePoolWithTag(notification, 'X66');

        }

        scannerContext->Rescan = FALSE;

        FltSetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, FLT_SET_CONTEXT_REPLACE_IF_EXISTS, scannerContext, NULL);


        FltReleaseContext(scannerContext);
    }


    return FLT_POSTOP_FINISHED_PROCESSING;
}



FLT_PREOP_CALLBACK_STATUS  ScannerPreSetInformation(
    PFLT_CALLBACK_DATA Data,
    PCFLT_RELATED_OBJECTS FltObjects,
    PVOID CompletionContext
)
{
    NTSTATUS status = FLT_PREOP_SUCCESS_NO_CALLBACK;
    PFILE_RENAME_INFORMATION renameInfo = NULL;
    PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
    PSCANNER_CONTEXT scannerContext = NULL;
    PSCANNER_NOTIFICATION notification = NULL;
    ULONG replyLen = 0;
    UNICODE_STRING extension = RTL_CONSTANT_STRING(L"exe");

    if (FltObjects->FileObject == NULL)
    {
        return status;
    }


    if (Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformation ||
        Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformationEx)
    {

        renameInfo = Data->Iopb->Parameters.SetFileInformation.InfoBuffer;


        status = FltGetDestinationFileNameInformation(FltObjects->Instance,
            FltObjects->FileObject,
            renameInfo->RootDirectory,
            renameInfo->FileName,
            renameInfo->FileNameLength,
            FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
            &FileNameInfo);

        if (NT_SUCCESS(status))
        {

            FltParseFileNameInformation(FileNameInfo);


            if (FileNameInfo->Extension.Length == 0)
            {
                FltReleaseFileNameInformation(FileNameInfo);
                return FLT_PREOP_SUCCESS_NO_CALLBACK;
            }


            if (RtlCompareUnicodeString(&extension, &FileNameInfo->Extension, TRUE) != 0)
            {
                FltReleaseFileNameInformation(FileNameInfo);
                return FLT_PREOP_SUCCESS_NO_CALLBACK;
            }


            /*DbgPrint("%wZ\n", FileNameInfo->Name);*/

            notification = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCANNER_NOTIFICATION), 'X66');
            if (notification == NULL)
            {
                FltReleaseFileNameInformation(FileNameInfo);
                return FLT_PREOP_SUCCESS_NO_CALLBACK;
            }

            replyLen = sizeof(SCANNER_REPLY);

            RtlCopyMemory(notification->PathName, FileNameInfo->Name.Buffer, FileNameInfo->Name.MaximumLength);

            status = FltSendMessage(ScannerData.Filter,
                &ScannerData.ClientPort,
                notification,
                sizeof(SCANNER_NOTIFICATION),
                notification,
                &replyLen,
                NULL
            );

            if (!NT_SUCCESS(status))
            {
                DbgPrint("Error FltSendMessage\n");
            }



            ExFreePoolWithTag(notification, 'X66');
            FltReleaseFileNameInformation(FileNameInfo);


        }

    }


    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Writing WDF Drivers 21 Oct 2019 OSR Seminar Space & ONLINE
Internals & Software Drivers 18 Nov 2019 Dulles, VA
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 27 Apr 2020 OSR Seminar Space & ONLINE