[note] 贴一段能实现文件隐藏的Minifilter

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

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

PFLT_FILTER filterHandle;
PWCHAR prefixName = L"invisible";
ULONG prefixLength = 9;

/*************************************************************************
    Prototypes
*************************************************************************/

NTSTATUS DriverEntry ( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath );
NTSTATUS PtUnload ( __in FLT_FILTER_UNLOAD_FLAGS Flags );

FLT_POSTOP_CALLBACK_STATUS MjDirectoryControlPostOperation ( __inout PFLT_CALLBACK_DATA Data,
                                                             __in PCFLT_RELATED_OBJECTS FltObjects,
                                                             __in_opt PVOID CompletionContext,
                                                             __in FLT_POST_OPERATION_FLAGS Flags );

BOOLEAN hasPrefix( PWCHAR name, ULONG length );
   
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, PtUnload)
#endif

CONST FLT_OPERATION_REGISTRATION Callbacks[] =
{
    { IRP_MJ_DIRECTORY_CONTROL,
      0,
      NULL,
      MjDirectoryControlPostOperation },

    { IRP_MJ_OPERATION_END }
};

CONST FLT_REGISTRATION FilterRegistration =
{
    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    0,                                  //  Flags
    NULL,                               //  Context
    Callbacks,                          //  Operation callbacks
    PtUnload,                           //  MiniFilterUnload
    NULL,                               //  InstanceSetup
    NULL,                               //  InstanceQueryTeardown
    NULL,                               //  InstanceTeardownStart
    NULL,                               //  InstanceTeardownComplete
    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent
};

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

    UNREFERENCED_PARAMETER( RegistryPath );

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

    if (NT_SUCCESS( status ))
    {
        status = FltStartFiltering( filterHandle );

        if (!NT_SUCCESS( status ))
        {
            FltUnregisterFilter( filterHandle );
        }
    }

    return status;
}

NTSTATUS PtUnload ( __in FLT_FILTER_UNLOAD_FLAGS Flags )
{
    UNREFERENCED_PARAMETER( Flags );
    PAGED_CODE();

    FltUnregisterFilter( filterHandle );

    return STATUS_SUCCESS;
}

FLT_POSTOP_CALLBACK_STATUS MjDirectoryControlPostOperation ( __inout PFLT_CALLBACK_DATA Data,
                                                             __in PCFLT_RELATED_OBJECTS FltObjects,
                                                             __in_opt PVOID CompletionContext,
                                                             __in FLT_POST_OPERATION_FLAGS Flags )
{
    ULONG length;
    ULONG nextOffset = 0;
    ULONG previousEntryWasDeleted = 0;
    PCHAR queryBuffer = 0;
    int modified = 0;
    int removedAllEntries = 1;

    PFILE_BOTH_DIR_INFORMATION currentFileInfo = 0;
    PFILE_BOTH_DIR_INFORMATION nextFileInfo = 0;
    PFILE_BOTH_DIR_INFORMATION previousFileInfo = 0;
   
    UNICODE_STRING fileName;
   
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    if( FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) )
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }
   
    if( Data->Iopb->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass == FileBothDirectoryInformation &&
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length > 0 &&
        NT_SUCCESS(Data->IoStatus.Status) )
    {
        currentFileInfo = (PFILE_BOTH_DIR_INFORMATION)Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;
        previousFileInfo = currentFileInfo;
           
        do
        {
            nextOffset = currentFileInfo->NextEntryOffset;
            nextFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)(currentFileInfo) + nextOffset);

            if( hasPrefix( currentFileInfo->FileName, currentFileInfo->FileNameLength ) )
            {
                if( nextOffset == 0 )
                {
                    previousFileInfo->NextEntryOffset = 0;
                }
                else
                {
                    previousFileInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileInfo - (PCHAR)previousFileInfo) + nextOffset;
                }
               
                modified = 1;
                previousEntryWasDeleted = 1;
            }
            else
            {
                removedAllEntries = 0;

                if( !previousEntryWasDeleted )
                {
                    previousFileInfo = currentFileInfo;
                }
                previousEntryWasDeleted = 0;
            }
           
            currentFileInfo = nextFileInfo;
        } while( nextOffset != 0 );

        if( modified )
        {
            if( removedAllEntries )
            {
                Data->IoStatus.Status = STATUS_NO_MORE_FILES;
            }
            else
            {
                FltSetCallbackDataDirty( Data );
            }
        }
    }
   
    return FLT_POSTOP_FINISHED_PROCESSING;
}

BOOLEAN hasPrefix( PWCHAR name, ULONG length )
{
    ULONG i;
    ULONG wcharLength = length / 2;

    if( wcharLength < prefixLength )
    {
        return FALSE;
    }

    for( i=0; i<prefixLength; i++ )
    {
        if( name[i] != prefixName[i] )
            return FALSE;
    }
   
    return TRUE;
}

posted @ 2010-10-01 01:32  Tbit  阅读(1124)  评论(1编辑  收藏  举报