static
FLT_POSTOP_CALLBACK_STATUS
    FileCreateFilterPostCallback
    (
        PFLT_CALLBACK_DATA Data,
        PCFLT_RELATED_OBJECTS FltObjects,
        PVOID CompletionContext,
        FLT_POST_OPERATION_FLAGS Flags
    )
{
    FLT_POSTOP_CALLBACK_STATUS status = FLT_POSTOP_FINISHED_PROCESSING;
    KLOCK_QUEUE_HANDLE hMutex = { 0 };
    PFLT_FILE_NAME_INFORMATION fileInfo = NULL;
    RU32 pid = 0;
    RU64 ts = 0;
    RU32 createOptions = 0;
    RU32 createDispositions = 0;
    _fileContext* context = NULL;
    
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );
    UNREFERENCED_PARAMETER( Flags );

    // We only care about user mode for now.
    if( UserMode != Data->RequestorMode ||
        STATUS_SUCCESS != Data->IoStatus.Status )
    {
        return status;
    }

    if( FILE_CREATED == Data->IoStatus.Information )
    {
        pid = (RU32)FltGetRequestorProcessId( Data );
        ts = rpal_time_getLocal();
        
        if( !NT_SUCCESS( FltGetFileNameInformation( Data,
                                                    FLT_FILE_NAME_NORMALIZED |
                                                    FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
                                                    &fileInfo ) ) )
        {
            rpal_debug_kernel( "Failed to get file name info" );
            fileInfo = NULL;
        }
        else
        {
            //rpal_debug_kernel( "NEW: %wZ", fileInfo->Name );
        }

        if( NULL != ( context = _getOrSetContext( Data ) ) )
        {
            context->isNew = TRUE;
            FltReleaseContext( (PFLT_CONTEXT)context );
        }

        KeAcquireInStackQueuedSpinLock( &g_collector_2_mutex, &hMutex );

        g_files[ g_nextFile ].pid = pid;
        g_files[ g_nextFile ].ts = ts;
        g_files[ g_nextFile ].uid = KERNEL_ACQ_NO_USER_ID;
        g_files[ g_nextFile ].action = KERNEL_ACQ_FILE_ACTION_ADDED;

        if( NULL != fileInfo )
        {
            copyUnicodeStringToBuffer( &fileInfo->Name,
                                       g_files[ g_nextFile ].path );

            FltReleaseFileNameInformation( fileInfo );
        }

        g_nextFile++;
        if( g_nextFile == _NUM_BUFFERED_FILES )
        {
            g_nextFile = 0;
        }

        KeReleaseInStackQueuedSpinLock( &hMutex );
    }

    createOptions = Data->Iopb->Parameters.Create.Options & 0x00FFFFFF;
    createDispositions = ( Data->Iopb->Parameters.Create.Options & 0xFF000000 ) >> 24;

    if( IS_FLAG_ENABLED( createOptions, FILE_DELETE_ON_CLOSE ) )
    {
        if( NULL != ( context = _getOrSetContext( Data ) ) )
        {
            context->isDelete = TRUE;
            FltReleaseContext( (PFLT_CONTEXT)context );
        }
    }

    return status;
}
static
FLT_POSTOP_CALLBACK_STATUS
    FileSetInfoFilterPostCallback
    (
        PFLT_CALLBACK_DATA Data,
        PCFLT_RELATED_OBJECTS FltObjects,
        PVOID CompletionContext,
        FLT_POST_OPERATION_FLAGS Flags
    )
{
    FLT_POSTOP_CALLBACK_STATUS status = FLT_POSTOP_FINISHED_PROCESSING;
    KLOCK_QUEUE_HANDLE hMutex = { 0 };
    PFLT_FILE_NAME_INFORMATION fileInfoSrc = NULL;
    PFLT_FILE_NAME_INFORMATION fileInfoDst = NULL;
    RU32 pid = 0;
    RU64 ts = 0;
    RU32 createOptions = 0;
    RU32 createDispositions = 0;
    PFILE_RENAME_INFORMATION renameInfo = NULL;
    _fileContext* context = NULL;

    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );
    UNREFERENCED_PARAMETER( Flags );

    // We only care about user mode for now.
    if( UserMode != Data->RequestorMode ||
        STATUS_SUCCESS != Data->IoStatus.Status )
    {
        return status;
    }

    if( FileRenameInformation == Data->Iopb->Parameters.SetFileInformation.FileInformationClass )
    {
        if( NULL != ( fileInfoSrc = (PFLT_FILE_NAME_INFORMATION)CompletionContext ) )
        {
            //rpal_debug_kernel( "MOVE OLD: %wZ", fileInfoSrc->Name );
        }
        else
        {
            rpal_debug_kernel( "Failed to get src file name info" );
        }

        renameInfo = (PFILE_RENAME_INFORMATION)Data->Iopb->Parameters.SetFileInformation.InfoBuffer;

        if( !NT_SUCCESS( FltGetDestinationFileNameInformation( FltObjects->Instance,
                                                               FltObjects->FileObject,
                                                               renameInfo->RootDirectory,
                                                               renameInfo->FileName,
                                                               renameInfo->FileNameLength,
                                                               FLT_FILE_NAME_NORMALIZED |
                                                               FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
                                                               &fileInfoDst ) ) )
        {
            rpal_debug_kernel( "Failed to get dst file name info" );
        }
        else
        {
            //rpal_debug_kernel( "MOVE TO: %wZ", fileInfoDst->Name );
        }

        pid = (RU32)FltGetRequestorProcessId( Data );
        ts = rpal_time_getLocal();

        createOptions = Data->Iopb->Parameters.Create.Options & 0x00FFFFFF;
        createDispositions = ( Data->Iopb->Parameters.Create.Options & 0xFF000000 ) >> 24;

        KeAcquireInStackQueuedSpinLock( &g_collector_2_mutex, &hMutex );

        g_files[ g_nextFile ].pid = pid;
        g_files[ g_nextFile ].ts = ts;
        g_files[ g_nextFile ].uid = KERNEL_ACQ_NO_USER_ID;

        // For compability with the user mode API we report file moves
        // as two different operations.

        // First we report the old file name.
        g_files[ g_nextFile ].action = KERNEL_ACQ_FILE_ACTION_RENAME_OLD;

        if( NULL != fileInfoSrc )
        {
            copyUnicodeStringToBuffer( &fileInfoSrc->Name,
                                       g_files[ g_nextFile ].path );

            FltReleaseFileNameInformation( fileInfoSrc );
        }

        g_nextFile++;
        if( g_nextFile == _NUM_BUFFERED_FILES )
        {
            g_nextFile = 0;
        }

        // Now report the new file name.
        g_files[ g_nextFile ].action = KERNEL_ACQ_FILE_ACTION_RENAME_NEW;

        if( NULL != fileInfoDst )
        {
            copyUnicodeStringToBuffer( &fileInfoDst->Name,
                                       g_files[ g_nextFile ].path );

            FltReleaseFileNameInformation( fileInfoDst );
        }

        g_nextFile++;
        if( g_nextFile == _NUM_BUFFERED_FILES )
        {
            g_nextFile = 0;
        }

        KeReleaseInStackQueuedSpinLock( &hMutex );
    }
    else if( FileDispositionInformationEx == Data->Iopb->Parameters.SetFileInformation.FileInformationClass ||
Ejemplo n.º 3
0
FLT_PREOP_CALLBACK_STATUS
FLTAPI
FilterPreCreate(
    FLT_CALLBACK_DATA* Data,
    PCFLT_RELATED_OBJECTS FltObjects,
    PVOID* CompletionContext
    )
{
    NTSTATUS status;
    FLT_FILE_NAME_INFORMATION *nameInformation;
    UNICODE_STRING *fullPath;

    status = FltGetFileNameInformation(
                Data,
                FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
                &nameInformation
                );

    if (status == STATUS_SUCCESS)
    {
        status = FltParseFileNameInformation(nameInformation);

        if (status == STATUS_SUCCESS)
        {
            FLT_FILE_LIST_ENTRY *file = FltFileList;

            fullPath = &nameInformation->Name;

            if ((Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess & FILE_EXECUTE) //Execute
                && (nameInformation->FinalComponent.Length == 16 //d3d8.dll/d3d9.dll
                || nameInformation->FinalComponent.Length == 18)) //d3d10.dll/d3d11.dll
            {
                if (wcsncmp(L"d3d8.dll", nameInformation->FinalComponent.Buffer, 8) == 0
                    || wcsncmp(L"d3d9.dll", nameInformation->FinalComponent.Buffer, 8) == 0
                    || wcsncmp(L"d3d10.dll", nameInformation->FinalComponent.Buffer, 9) == 0
                    || wcsncmp(L"d3d11.dll", nameInformation->FinalComponent.Buffer, 9) == 0)
                {
                    PROCESSID processId;
                    DEVICE_EXTENSION *deviceExtension;

                    processId = FltGetRequestorProcessId(Data);

                    deviceExtension = g_DeviceObject->DeviceExtension;
                    deviceExtension->imageEvent.processID = processId;

                    KeSetEvent(PushGpuAccelerationEvent, 0, FALSE);
                    KeClearEvent(PushGpuAccelerationEvent);

                    DbgPrint("[PUSH] %u loaded %wZ\n", processId, fullPath);
                }
            }

            while (file != 0)
            {
                if (fullPath->Length == file->NameLength
                    && wcsncmp(file->Name, fullPath->Buffer, file->NameLength / sizeof(WCHAR)) == 0)
                {
                    UNICODE_STRING newName;
                    UNICODE_STRING redirect;
                    UNICODE_STRING *currentName;
                    UINT16 newNameSize;
                    WCHAR *buffer;

                    //DbgPrint("[PUSH] %ws matches %wZ", file->Name, fullPath);

                    RtlInitUnicodeString(&newName, PUSH_RAMDISK_DEVICE_NAME L"\\");

                    // Calculate the size of the name
                    newNameSize = newName.Length + nameInformation->FinalComponent.Length;

                    redirect.Length = newName.Length;
                    redirect.MaximumLength = newNameSize;
                    redirect.Buffer = ExAllocatePool(NonPagedPool, newNameSize);

                    // Copy ramdisk device name into buffer
                    RtlCopyMemory(redirect.Buffer, newName.Buffer, newName.Length);

                    // Append original file name
                    //RtlAppendUnicodeStringToString(&redirect, &nameInformation->FinalComponent);
                    buffer = &redirect.Buffer[redirect.Length / sizeof(WCHAR)];

                    RtlMoveMemory(
                        buffer,
                        nameInformation->FinalComponent.Buffer,
                        nameInformation->FinalComponent.Length
                        );

                    redirect.Length += nameInformation->FinalComponent.Length;
                    currentName = &Data->Iopb->TargetFileObject->FileName;

                    // Throw away the current file name
                    ExFreePool(currentName->Buffer);

                    currentName->Length = 0;
                    currentName->MaximumLength = redirect.MaximumLength;
                    currentName->Buffer = ExAllocatePool(NonPagedPool, redirect.MaximumLength);

                    // Copy new path to buffer
                    RtlCopyUnicodeString(currentName, &redirect);

                    // Be nice and give back what was given to us
                    ExFreePool(redirect.Buffer);

                    Data->IoStatus.Information = IO_REPARSE;
                    Data->IoStatus.Status = STATUS_REPARSE;
                    Data->Iopb->TargetFileObject->RelatedFileObject = NULL;

                    FltSetCallbackDataDirty(Data);

                    return FLT_PREOP_COMPLETE;
                }

                file = file->NextEntry;
            }
        }
    }

    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}