⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mspylib.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 2 页
字号:

    RecordList - Where we want to save the data

Return Value:

    None.

--*/
{
    PRECORD_DATA recordData = &RecordList->LogRecord.Data;

    recordData->Status = Data->IoStatus.Status;
    recordData->Information = Data->IoStatus.Information;
    KeQuerySystemTime( &recordData->CompletionTime );
}


VOID
SpyLogTransactionNofity (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __inout PRECORD_LIST RecordList,
    __in ULONG TransactionNotification
    )
/*++

Routine Description:

    This routine logs the transaction notification.

Arguments:

    FltObjects - Pointer to the io objects involved in this operation.

    RecordList - Where we want to save the data

    TransactionNotification - Notification for this transaction.

Return Value:

    None.

--*/
{
    PRECORD_DATA recordData = &RecordList->LogRecord.Data;
    PDEVICE_OBJECT devObj;
    NTSTATUS status;

    status = FltGetDeviceObject(FltObjects->Volume,&devObj);
    if (NT_SUCCESS(status)) {

        ObDereferenceObject(devObj);

    } else {

        devObj = NULL;
    }


    recordData->CallbackMajorId = IRP_MJ_TRANSACTION_NOTIFY;
    recordData->CallbackMinorId = (UCHAR)TransactionNotification;

    recordData->DeviceObject    = (FILE_ID)devObj;
    recordData->FileObject      = (FILE_ID)FltObjects->FileObject;
    recordData->Transaction     = (FILE_ID)FltObjects->Transaction;
    recordData->ProcessId       = (FILE_ID)PsGetCurrentProcessId();
    recordData->ThreadId        = (FILE_ID)PsGetCurrentThreadId();

    KeQuerySystemTime( &recordData->OriginatingTime );
}


VOID
SpyLog (
    __in PRECORD_LIST RecordList
    )
/*++

Routine Description:

    This routine inserts the given log record into the list to be sent
    to the user mode application.

    NOTE:  This code must be NON-PAGED because it can be called on the
           paging path or at DPC level and uses a spin-lock

Arguments:

    RecordList - The record to append to the MiniSpyData.OutputBufferList

Return Value:

    The function returns STATUS_SUCCESS.



--*/
{
    KIRQL oldIrql;

    KeAcquireSpinLock(&MiniSpyData.OutputBufferLock, &oldIrql);
    InsertTailList(&MiniSpyData.OutputBufferList, &RecordList->List);
    KeReleaseSpinLock(&MiniSpyData.OutputBufferLock, oldIrql);
}


NTSTATUS
SpyGetLog (
    __out_bcount_part(OutputBufferLength,*ReturnOutputBufferLength) PUCHAR OutputBuffer,
    __in ULONG OutputBufferLength,
    __out PULONG ReturnOutputBufferLength
    )
/*++

Routine Description:
    This function fills OutputBuffer with as many LOG_RECORDs as possible.
    The LOG_RECORDs are variable sizes and are tightly packed in the
    OutputBuffer.

    NOTE:  This code must be NON-PAGED because it uses a spin-lock.

Arguments:
    OutputBuffer - The user's buffer to fill with the log data we have
        collected

    OutputBufferLength - The size in bytes of OutputBuffer

    ReturnOutputBufferLength - The amount of data actually written into the
        OutputBuffer.

Return Value:
    STATUS_SUCCESS if some records were able to be written to the OutputBuffer.

    STATUS_NO_MORE_ENTRIES if we have no data to return.

    STATUS_BUFFER_TOO_SMALL if the OutputBuffer is too small to
        hold even one record and we have data to return.

--*/
{
    PLIST_ENTRY pList;
    ULONG bytesWritten = 0;
    PLOG_RECORD pLogRecord;
    NTSTATUS status = STATUS_NO_MORE_ENTRIES;
    PRECORD_LIST pRecordList;
    KIRQL oldIrql;
    BOOLEAN recordsAvailable = FALSE;

    KeAcquireSpinLock( &MiniSpyData.OutputBufferLock, &oldIrql );

    while (!IsListEmpty( &MiniSpyData.OutputBufferList ) && (OutputBufferLength > 0)) {

        //
        //  Mark we have records
        //

        recordsAvailable = TRUE;

        //
        //  Get the next available record
        //

        pList = RemoveHeadList( &MiniSpyData.OutputBufferList );

        pRecordList = CONTAINING_RECORD( pList, RECORD_LIST, List );

        pLogRecord = &pRecordList->LogRecord;

        //
        //  If no filename was set then make it into a NULL file name.
        //

        if (REMAINING_NAME_SPACE( pLogRecord ) == MAX_NAME_SPACE) {

            //
            //  We don't have a name, so return an empty string.
            //  We have to always start a new log record on a PVOID aligned boundary.
            //

            pLogRecord->Length += ROUND_TO_SIZE( sizeof( UNICODE_NULL ), sizeof( PVOID ) );
            pLogRecord->Name[0] = UNICODE_NULL;
        }

        //
        //  Put it back if we've run out of room.
        //

        if (OutputBufferLength < pLogRecord->Length) {

            InsertHeadList( &MiniSpyData.OutputBufferList, pList );
            break;
        }

        KeReleaseSpinLock( &MiniSpyData.OutputBufferLock, oldIrql );

        //
        //  The lock is released, return the data, adjust pointers.
        //  Protect access to raw user-mode OutputBuffer with an exception handler
        //

        try {
            RtlCopyMemory( OutputBuffer, pLogRecord, pLogRecord->Length );
        } except( EXCEPTION_EXECUTE_HANDLER ) {

            //
            //  Put the record back in
            //

            KeAcquireSpinLock( &MiniSpyData.OutputBufferLock, &oldIrql );
            InsertHeadList( &MiniSpyData.OutputBufferList, pList );
            KeReleaseSpinLock( &MiniSpyData.OutputBufferLock, oldIrql );

            return GetExceptionCode();

        }

        bytesWritten += pLogRecord->Length;

        OutputBufferLength -= pLogRecord->Length;

        OutputBuffer += pLogRecord->Length;

        SpyFreeRecord( pRecordList );

        //
        //  Relock the list
        //

        KeAcquireSpinLock( &MiniSpyData.OutputBufferLock, &oldIrql );
    }

    KeReleaseSpinLock( &MiniSpyData.OutputBufferLock, oldIrql );

    //
    //  Set proper status
    //

    if ((bytesWritten == 0) && recordsAvailable) {

        //
        //  There were records to be sent up but
        //  there was not enough room in the buffer.
        //

        status = STATUS_BUFFER_TOO_SMALL;

    } else if (bytesWritten > 0) {

        //
        //  We were able to write some data to the output buffer,
        //  so this was a success.
        //

        status = STATUS_SUCCESS;
    }

    *ReturnOutputBufferLength = bytesWritten;

    return status;
}


VOID
SpyEmptyOutputBufferList (
    VOID
    )
/*++

Routine Description:

    This routine frees all the remaining log records in the OutputBufferList
    that are not going to get sent up to the user mode application since
    MiniSpy is shutting down.

    NOTE:  This code must be NON-PAGED because it uses a spin-lock

Arguments:

    None.

Return Value:

    None.

--*/
{
    PLIST_ENTRY pList;
    PRECORD_LIST pRecordList;
    KIRQL oldIrql;

    KeAcquireSpinLock( &MiniSpyData.OutputBufferLock, &oldIrql );

    while (!IsListEmpty( &MiniSpyData.OutputBufferList )) {

        pList = RemoveHeadList( &MiniSpyData.OutputBufferList );
        KeReleaseSpinLock( &MiniSpyData.OutputBufferLock, oldIrql );

        pRecordList = CONTAINING_RECORD( pList, RECORD_LIST, List );

        SpyFreeRecord( pRecordList );

        KeAcquireSpinLock( &MiniSpyData.OutputBufferLock, &oldIrql );
    }

    KeReleaseSpinLock( &MiniSpyData.OutputBufferLock, oldIrql );
}

//---------------------------------------------------------------------------
//                    Logging routines
//---------------------------------------------------------------------------

VOID
SpyReadDriverParameters (
    __in PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This routine tries to read the MiniSpy-specific parameters from
    the registry.  These values will be found in the registry location
    indicated by the RegistryPath passed in.

Arguments:

    RegistryPath - the path key which contains the values that are
        the MiniSpy parameters

Return Value:

    None.

--*/
{
    OBJECT_ATTRIBUTES attributes;
    HANDLE driverRegKey;
    NTSTATUS status;
    ULONG resultLength;
    UNICODE_STRING valueName;
    PKEY_VALUE_PARTIAL_INFORMATION pValuePartialInfo;
    UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( LONG )];

    //
    //  Open the registry
    //

    InitializeObjectAttributes( &attributes,
                                RegistryPath,
                                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL );

    status = ZwOpenKey( &driverRegKey,
                        KEY_READ,
                        &attributes );

    if (!NT_SUCCESS( status )) {

        return;
    }

    //
    // Read the MaxRecordsToAllocate entry from the registry
    //

    RtlInitUnicodeString( &valueName, MAX_RECORDS_TO_ALLOCATE );

    status = ZwQueryValueKey( driverRegKey,
                              &valueName,
                              KeyValuePartialInformation,
                              buffer,
                              sizeof(buffer),
                              &resultLength );

    if (NT_SUCCESS( status )) {

        pValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
        ASSERT( pValuePartialInfo->Type == REG_DWORD );
        MiniSpyData.MaxRecordsToAllocate = *((PLONG)&(pValuePartialInfo->Data));
    }

    //
    // Read the NameQueryMethod entry from the registry
    //

    RtlInitUnicodeString( &valueName, NAME_QUERY_METHOD );

    status = ZwQueryValueKey( driverRegKey,
                              &valueName,
                              KeyValuePartialInformation,
                              buffer,
                              sizeof(buffer),
                              &resultLength );

    if (NT_SUCCESS( status )) {

        pValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
        ASSERT( pValuePartialInfo->Type == REG_DWORD );
        MiniSpyData.NameQueryMethod = *((PLONG)&(pValuePartialInfo->Data));
    }

    ZwClose(driverRegKey);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -