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

📄 fspyhash.c

📁 修改过的filespy驱动 移植了tooflat部分代码到filespy中,hook 了write 和read ,加密标记还没有处理好.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1989-1999  Microsoft Corporation

Module Name:

    filespy.c

Abstract:

    This module contains all of the routines for tracking names by
    hashing the FileObject.  This cache is limited in size by the
    following registry setting "MaxNames".

Environment:

    Kernel mode

--*/

#include <ntifs.h>
#include "filespy.h"
#include "fspyKern.h"
#include "namelookup.h"

#if !USE_STREAM_CONTEXTS

////////////////////////////////////////////////////////////////////////
//
//                    Local definitions
//
////////////////////////////////////////////////////////////////////////

#define HASH_FUNC(FileObject) \
    (((UINT_PTR)(FileObject) >> 8) & (HASH_SIZE - 1))

////////////////////////////////////////////////////////////////////////
//
//                    Global Variables
//
////////////////////////////////////////////////////////////////////////

//
//  NOTE:  Must use KSPIN_LOCKs to synchronize access to hash buckets since
//         we may try to acquire them at DISPATCH_LEVEL.
//

LIST_ENTRY gHashTable[HASH_SIZE];
KSPIN_LOCK gHashLockTable[HASH_SIZE];
ULONG gHashMaxCounters[HASH_SIZE];
ULONG gHashCurrentCounters[HASH_SIZE];

UNICODE_STRING OutOfBuffers = CONSTANT_UNICODE_STRING(L"[-=Out Of Buffers=-]");
UNICODE_STRING PagingFile = CONSTANT_UNICODE_STRING(L"[-=Paging File=-]");


////////////////////////////////////////////////////////////////////////
//
//                    Local prototypes
//
////////////////////////////////////////////////////////////////////////

VOID
SpyDeleteContextCallback(
    IN PVOID Context
    );


//
//  Linker commands
//

#ifdef ALLOC_PRAGMA

#pragma alloc_text(PAGE, SpyInitNamingEnvironment)
#pragma alloc_text(PAGE, SpyInitDeviceNamingEnvironment)
#pragma alloc_text(PAGE, SpyCleanupDeviceNamingEnvironment)

#endif  // ALLOC_PRAGMA


////////////////////////////////////////////////////////////////////////
//
//                    Main routines
//
////////////////////////////////////////////////////////////////////////


VOID
SpyInitNamingEnvironment(
    VOID
    )
/*++

Routine Description:

    Init global variables.

Arguments:

    None

Return Value:

    None.

--*/
{
    int i;

    //
    //  Initialize the hash table.
    //

    for (i = 0; i < HASH_SIZE; i++){

        InitializeListHead( &gHashTable[i] );
        KeInitializeSpinLock( &gHashLockTable[i] );
    }
}


VOID
SpyInitDeviceNamingEnvironment (
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:

    Initialize the per DeviceObject naming environment.

Arguments:

    DeviceObject - The device object to initialize.

Return Value:

    None.

--*/
{
    UNREFERENCED_PARAMETER( DeviceObject );
}


VOID
SpyCleanupDeviceNamingEnvironment (
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:

    Initialize the per DeviceObject naming environment.

Arguments:

    DeviceObject - The device object to initialize.

Return Value:

    None.

--*/
{
    UNREFERENCED_PARAMETER( DeviceObject );
}


VOID
SpyLogIrp (
    IN PIRP Irp,
    OUT PRECORD_LIST RecordList
    )
/*++

Routine Description:

    Records the Irp necessary information according to LoggingFlags in
    RecordList.  For any activity on the Irp path of a device being
    logged, this function should get called twice: once on the IRPs
    originating path and once on the IRPs completion path.

Arguments:

    Irp - The Irp that contains the information we want to record.
    LoggingFlags - The flags that say what to log.
    RecordList - The PRECORD_LIST in which the Irp information is stored.

Return Value:

    None.

--*/
{
    PIO_STACK_LOCATION pIrpStack;
    PRECORD_IRP pRecordIrp;
    ULONG lookupFlags;

    pRecordIrp = &RecordList->LogRecord.Record.RecordIrp;

    pIrpStack = IoGetCurrentIrpStackLocation(Irp);

    //
    //  Record the information we use for an originating Irp.  We first
    //  need to initialize some of the RECORD_LIST and RECORD_IRP fields.
    //  Then get the interesting information from the Irp.
    //

    SetFlag(RecordList->LogRecord.RecordType, RECORD_TYPE_IRP);

    pRecordIrp->IrpMajor = pIrpStack->MajorFunction;
    pRecordIrp->IrpMinor = pIrpStack->MinorFunction;
    pRecordIrp->IrpFlags = Irp->Flags;
    pRecordIrp->FileObject = (FILE_ID)pIrpStack->FileObject;
    pRecordIrp->DeviceObject = (FILE_ID)pIrpStack->DeviceObject;
    pRecordIrp->ProcessId = (FILE_ID)PsGetCurrentProcessId();
    pRecordIrp->ThreadId = (FILE_ID)PsGetCurrentThreadId();
    pRecordIrp->Argument1 = pIrpStack->Parameters.Others.Argument1;
    pRecordIrp->Argument2 = pIrpStack->Parameters.Others.Argument2;
    pRecordIrp->Argument3 = pIrpStack->Parameters.Others.Argument3;
    pRecordIrp->Argument4 = pIrpStack->Parameters.Others.Argument4;

    if (IRP_MJ_CREATE == pRecordIrp->IrpMajor) {

        //
        //  Only record the desired access if this is a CREATE IRP.
        //

        pRecordIrp->DesiredAccess = pIrpStack->Parameters.Create.SecurityContext->DesiredAccess;
    }

    KeQuerySystemTime(&(pRecordIrp->OriginatingTime));

    lookupFlags = 0;

    switch (pIrpStack->MajorFunction) {

        case IRP_MJ_CREATE:

            //
            //  This is a CREATE so we need to invalidate the name currently
            //  stored in the name cache for this FileObject.
            //

            SpyNameDelete( pIrpStack->FileObject );

            //
            //  Flag in Create
            //

            SetFlag(lookupFlags, NLFL_IN_CREATE);

            //
            //  Flag if opening the directory of the given file.
            //

            if (FlagOn(pIrpStack->Flags, SL_OPEN_TARGET_DIRECTORY)) {

                SetFlag(lookupFlags, NLFL_OPEN_TARGET_DIR);
            }

            //
            //  Flag if opening by ID.
            //

            if (FlagOn(pIrpStack->Parameters.Create.Options,
                       FILE_OPEN_BY_FILE_ID )) {

                SetFlag(lookupFlags, NLFL_OPEN_BY_ID);
            }

            break;

        case IRP_MJ_CLOSE:
            //
            //  We can only look up the name in the name cache if this is a
            //  CLOSE.  It is possible that the close could be occurring during
            //  a cleanup operation in the file system (i.e., before we have
            //  received the cleanup completion) and requesting the name would
            //  cause a deadlock in the file system.
            //

            SetFlag(lookupFlags, NLFL_ONLY_CHECK_CACHE);
            break;
    }

    //
    //  If the flag IRP_PAGING_IO is set in this IRP, we cannot query the name
    //  because it can lead to deadlocks.  Therefore, add in the flag so that
    //  we will only try to find the name in our cache.
    //

    if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {

        ASSERT( !FlagOn( lookupFlags, NLFL_NO_LOOKUP ) );

        SetFlag( lookupFlags, NLFL_ONLY_CHECK_CACHE );
    }

    SpySetName( RecordList,
                pIrpStack->DeviceObject,
                pIrpStack->FileObject,
                lookupFlags,
                NULL );
}


VOID
SpyLogIrpCompletion (
    IN PIRP Irp,
    OUT PRECORD_LIST RecordList
    )
/*++

Routine Description:

    Records the Irp necessary information according to LoggingFlags in
    RecordList.  For any activity on the Irp path of a device being
    logged, this function should get called twice: once on the IRPs
    originating path and once on the IRPs completion path.

Arguments:

    Irp - The Irp that contains the information we want to record.
    LoggingFlags - The flags that say what to log.
    RecordList - The PRECORD_LIST in which the Irp information is stored.

Return Value:

    None.

--*/
{
    PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_OBJECT deviceObject = pIrpStack->DeviceObject;
    PRECORD_IRP pRecordIrp;

    //
    //  Process the log record
    //

    if (SHOULD_LOG( deviceObject )) {

        pRecordIrp = &RecordList->LogRecord.Record.RecordIrp;

        //
        // Record the information we use for a completion Irp.
        //

        pRecordIrp->ReturnStatus = Irp->IoStatus.Status;
        pRecordIrp->ReturnInformation = Irp->IoStatus.Information;
        KeQuerySystemTime(&pRecordIrp->CompletionTime);

        //
        //  Add RecordList to our gOutputBufferList so that it gets up to
        //  the user
        //

        SpyLog( RecordList );

    } else {

        if (RecordList) {

            //
            //  Context is set with a RECORD_LIST, but we are no longer
            //  logging so free this record.
            //

            SpyFreeRecord( RecordList );
        }
    }

    switch (pIrpStack->MajorFunction) {

        case IRP_MJ_CREATE:
            //
            //  If the operation failed remove the name from the cache because
            //  it is stale
            //

            if (!NT_SUCCESS(Irp->IoStatus.Status) &&
                (pIrpStack->FileObject != NULL)) {

                SpyNameDelete(pIrpStack->FileObject);
            }
            break;

        case IRP_MJ_CLOSE:

            //
            //  Always remove the name on close
            //

            SpyNameDelete(pIrpStack->FileObject);
            break;


        case IRP_MJ_SET_INFORMATION:

⌨️ 快捷键说明

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