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

📄 filespy.c

📁 对本程序不隐藏 对其他程序隐藏
💻 C
📖 第 1 页 / 共 5 页
字号:
//
//  VERSION NOTE:
//
//  There are 6 FastIO routines for which file system filters are bypassed as
//  the requests are passed directly to the base file system.  These 6 routines
//  are AcquireFileForNtCreateSection, ReleaseFileForNtCreateSection,
//  AcquireForModWrite, ReleaseForModWrite, AcquireForCcFlush, and
//  ReleaseForCcFlush.
//
//  In Windows XP and later, the FsFilter callbacks were introduced to allow
//  filters to safely hook these operations.  See the IFS Kit documentation for
//  more details on how these new interfaces work.
//
//  MULTIVERSION NOTE:
//
//  If built for Windows XP or later, this driver is built to run on
//  multiple versions.  When this is the case, we will test
//  for the presence of FsFilter callbacks registration API.  If we have it,
//  then we will register for those callbacks, otherwise, we will not.
//

#if WINVER >= 0x0501

    {
        FS_FILTER_CALLBACKS fsFilterCallbacks;

        if (IS_WINDOWSXP_OR_LATER()) {

            ASSERT( NULL != gSpyDynamicFunctions.RegisterFileSystemFilterCallbacks );

            //
            //  This version of the OS exports
            //  FsRtlRegisterFileSystemFilterCallbacks, therefore it must
            //  support the FsFilter callbacks interface.  We will register to
            //  receive callbacks for these operations.
            //

            //
            //  Setup the callbacks for the operations we receive through
            //  the FsFilter interface.
            //

            fsFilterCallbacks.SizeOfFsFilterCallbacks = sizeof( FS_FILTER_CALLBACKS );
            fsFilterCallbacks.PreAcquireForSectionSynchronization = SpyPreFsFilterOperation;
            fsFilterCallbacks.PostAcquireForSectionSynchronization = SpyPostFsFilterOperation;
            fsFilterCallbacks.PreReleaseForSectionSynchronization = SpyPreFsFilterOperation;
            fsFilterCallbacks.PostReleaseForSectionSynchronization = SpyPostFsFilterOperation;
            fsFilterCallbacks.PreAcquireForCcFlush = SpyPreFsFilterOperation;
            fsFilterCallbacks.PostAcquireForCcFlush = SpyPostFsFilterOperation;
            fsFilterCallbacks.PreReleaseForCcFlush = SpyPreFsFilterOperation;
            fsFilterCallbacks.PostReleaseForCcFlush = SpyPostFsFilterOperation;
            fsFilterCallbacks.PreAcquireForModifiedPageWriter = SpyPreFsFilterOperation;
            fsFilterCallbacks.PostAcquireForModifiedPageWriter = SpyPostFsFilterOperation;
            fsFilterCallbacks.PreReleaseForModifiedPageWriter = SpyPreFsFilterOperation;
            fsFilterCallbacks.PostReleaseForModifiedPageWriter = SpyPostFsFilterOperation;

            status = (gSpyDynamicFunctions.RegisterFileSystemFilterCallbacks)( DriverObject,
                                                                              &fsFilterCallbacks );

            if (!NT_SUCCESS( status )) {

                DriverObject->FastIoDispatch = NULL;
                ExFreePoolWithTag( fastIoDispatch, FILESPY_POOL_TAG );
                IoDeleteDevice( gControlDeviceObject );
                return status;
            }
        }
    }
#endif

    //////////////////////////////////////////////////////////////////////
    //
    //  Initialize global data structures that are used for FileSpy's
    //  logging of I/O operations.
    //
    //////////////////////////////////////////////////////////////////////

    //
    //  A fast mutex was used in this case because the mutex is never acquired
    //  at DPC level or above.  Spinlocks were chosen in other cases because
    //  they are acquired at DPC level or above.  Another consideration is
    //  that on an MP machine, a spin lock will literally spin trying to
    //  acquire the lock when the lock is already acquired.  Acquiring a
    //  previously acquired fast mutex will suspend the thread, thus freeing
    //  up the processor.
    //

    ExInitializeFastMutex( &gSpyDeviceExtensionListLock );
    InitializeListHead( &gSpyDeviceExtensionList );

    KeInitializeSpinLock( &gControlDeviceStateLock );

//    InitializeListHead( &gOutputBufferList );

//    KeInitializeSpinLock( &gOutputBufferLock );
//    KeInitializeSpinLock( &gLogSequenceLock );

    ExInitializeFastMutex( &gSpyAttachLock );

#ifndef MEMORY_DBG

    //
    //  When we aren't debugging our memory usage, we want to allocate
    //  memory from a look-aside list for better performance.  Unfortunately,
    //  we cannot benefit from the memory debugging help of the Driver
    //  Verifier if we allocate memory from a look-aside list.
    //

//    ExInitializeNPagedLookasideList( &gFreeBufferList,
//                                     NULL/*ExAllocatePoolWithTag*/,
//                                     NULL/*ExFreePool*/,
//                                     0,
//                                     RECORD_SIZE,
//                                     FILESPY_LOGRECORD_TAG,
//                                     100 );
#endif


    //
    //  Initialize the naming environment
    //

//    SpyInitNamingEnvironment();

    //
    //  Init internal strings
    //

//    RtlInitUnicodeString(&gVolumeString, L"VOLUME");
//    RtlInitUnicodeString(&gOverrunString, L"......");
//    RtlInitUnicodeString(&gPagingIoString, L"Paging IO");

    //
    //  If we are supposed to attach to all devices, register a callback
    //  with IoRegisterFsRegistrationChange so that we are called whenever a
    //  file system registers with the IO Manager.
    //
    //  VERSION NOTE:
    //
    //  On Windows XP and later this will also enumerate all existing file
    //  systems (except the RAW file systems).  On Windows 2000 this does not
    //  enumerate the file systems that were loaded before this filter was
    //  loaded.
    //

/*    if (gFileSpyAttachMode == FILESPY_ATTACH_ALL_VOLUMES) {

        status = IoRegisterFsRegistrationChange( DriverObject,
                                                 SpyFsNotification );

        if (!NT_SUCCESS( status )) {

            SPY_LOG_PRINT( SPYDEBUG_ERROR,
                           ("FileSpy!DriverEntry: Error registering FS change notification, status=%08x\n",
                            status) );

            DriverObject->FastIoDispatch = NULL;
            ExFreePoolWithTag( fastIoDispatch, FILESPY_POOL_TAG );
            IoDeleteDevice( gControlDeviceObject );
            return status;
        }
    }*/

    //
    //  Clear the initializing flag on the control device object since we
    //  have now successfully initialized everything.
    //

    ClearFlag( gControlDeviceObject->Flags, DO_DEVICE_INITIALIZING );

	PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);

    return STATUS_SUCCESS;
}

#if DBG && WINVER >= 0x0501

VOID
DriverUnload (
    IN PDRIVER_OBJECT DriverObject
    )

/*++

Routine Description:

    This routine is called when a driver can be unloaded.  This performs all of
    the necessary cleanup for unloading the driver from memory.  Note that an
    error can not be returned from this routine.

    When a request is made to unload a driver the IO System will cache that
    information and not actually call this routine until the following states
    have occurred:
    - All device objects which belong to this filter are at the top of their
      respective attachment chains.
    - All handle counts for all device objects which belong to this filter have
      gone to zero.

    WARNING: Microsoft does not officially support the unloading of File
             System Filter Drivers.  This is an example of how to unload
             your driver if you would like to use it during development.
             This should not be made available in production code.

Arguments:

    DriverObject - Driver object for this module

Return Value:

    None.

--*/

{
    PFILESPY_DEVICE_EXTENSION devExt;
    PFAST_IO_DISPATCH fastIoDispatch;
    NTSTATUS status;
    ULONG numDevices;
    ULONG i;
    LARGE_INTEGER interval;
    UNICODE_STRING linkString;
#   define DEVOBJ_LIST_SIZE 64
    PDEVICE_OBJECT devList[DEVOBJ_LIST_SIZE];

    ASSERT(DriverObject == gFileSpyDriverObject);

    
      //
      // Record : Add by lwf : 07-06-19
      // Purpose: Free the room of storing  
      //
      
      if( NULL != g_szHiddenDir ){
      
          ExFreePoolWithTag( g_szHiddenDir, FILESPY_POOL_TAG );
      }  
      
      if( NULL != g_szPrivProcName){
      
          ExFreePoolWithTag( g_szPrivProcName,FILESPY_POOL_TAG );
      }
      
//    SPY_LOG_PRINT( SPYDEBUG_DISPLAY_ATTACHMENT_NAMES,
//                   ("FileSpy!DriverUnload:                        Unloading Driver (%p)\n",
//                    DriverObject) );

    //
    //  Remove the symbolic link so no one else will be able to find it.
    //

    RtlInitUnicodeString( &linkString, FILESPY_DOSDEVICE_NAME );
    IoDeleteSymbolicLink( &linkString );

    //
    //  Don't get anymore file system change notifications
    //

    IoUnregisterFsRegistrationChange( DriverObject, SpyFsNotification );

    //
    //  Free the name buffer lookaside list.
    //

    ExDeletePagedLookasideList( &gFileSpyNameBufferLookasideList );

    //
    //  Delete the free buffer lookaside list.
    //

#ifndef MEMORY_DBG
//    ExDeleteNPagedLookasideList( &gFreeBufferList );
#endif

    //
    //  This is the loop that will go through all of the devices we are attached
    //  to and detach from them.  Since we don't know how many there are and
    //  we don't want to allocate memory (because we can't return an error)
    //  we will free them in chunks using a local array on the stack.
    //

    for (;;) {

        //
        //  Get what device objects we can for this driver.  Quit if there
        //  are not any more.  Note that this routine should always be defined
        //  since this routine is only compiled for Windows XP and later.
        //

        ASSERT( NULL != gSpyDynamicFunctions.EnumerateDeviceObjectList );
        status = (gSpyDynamicFunctions.EnumerateDeviceObjectList)(
                        DriverObject,
                        devList,
                        sizeof(devList),
                        &numDevices);

        if (numDevices <= 0)  {

            break;
        }

        numDevices = min( numDevices, DEVOBJ_LIST_SIZE );

        //
        //  First go through the list and detach each of the devices.
        //  Our control device object does not have a DeviceExtension and
        //  is not attached to anything so don't detach it.
        //

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

            devExt = devList[i]->DeviceExtension;
            if (NULL != devExt) {

                IoDetachDevice( devExt->NLExtHeader.AttachedToDeviceObject );
            }
        }

        //
        //  The IO Manager does not currently add a reference count to a device
        //  object for each outstanding IRP.  This means there is no way to
        //  know if there are any outstanding IRPs on the given device.
        //  We are going to wait for a reasonable amount of time for pending
        //  IRPs to complete.
        //
        //  WARNING: This does not work 100% of the time and the driver may be
        //           unloaded before all IRPs are completed during high stress
        //           situations.  The system will fault if this occurs.  This
        //           is a sample of how to do this during testing.  This is
        //           not recommended for production code.
        //

        interval.QuadPart = (5 * DELAY_ONE_SECOND);      //delay 5 seconds
        KeDelayExecutionThread( KernelMode, FALSE, &interval );

        //
        //  Now go back through the list and delete the device objects.
        //

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

            //
            //  See if this is our control device object.  If not then cleanup
            //  the device extension.  If so then clear the global pointer
            //  that references it.
            //

            if (NULL != devList[i]->DeviceExtension) {

                SpyCleanupMountedDevice( devList[i] );

            } else {

                ASSERT(devList[i] == gControlDeviceObject);
                ASSERT(gControlDeviceState == CLOSED);
                gControlDeviceObject = NULL;
            }

            //
            //  Delete the device object, remove reference counts added by
            //  IoEnumerateDeviceObjectList.  Note that the delete does
            //  not actually occur until the reference count goes to zero.
            //

            IoDeleteDevice( devList[i] );
            ObDereferenceObject( devList[i] );
        }
    }

    //
    //  Delete the look aside list.
    //

    ASSERT(IsListEmpty( &gSpyDeviceExtensionList ));

#ifndef MEMORY_DBG
//    ExDeleteNPagedLookasideList( &gFreeBufferList );
#endif

    //
    //  Free our FastIO table
    //

    fastIoDispatch = DriverObject->FastIoDispatch;
    DriverObject->FastIoDispatch = NULL;
    ExFreePoolWithTag( fastIoDispatch, FILESPY_POOL_TAG );

//    SPY_LOG_PRINT( SPYDEBUG_DISPLAY_ATTACHMENT_NAMES,
//                   ("FileSpy!DriverUnload:                        Unloading Complete (%p)\n",
//                    DriverObject) );
}

#endif

VOID
SpyFsNotification (
    IN PDEVICE_OBJECT DeviceObject,
    IN BOOLEAN FsActive
    )
/*++

Routine Description:

    This routine is invoked whenever a file system has either registered or
    unregistered itself as an active file system.

    For the former case, this routine creates a device object and attaches it
    to the specified file system's device object.  This allows this driver
    to filter all requests to that file system.

    For the latter case, this file system's device object is located,
    detached, and deleted.  This removes this file system as a filter for
    the specified file system.

Arguments:

    DeviceObject - Pointer to the file system's device object.

    FsActive - Boolean indicating whether the file system has registered
        (TRUE) or unregistered (FALSE) itself as an active file system.

Return Value:

    None.

--*/
{
    PNAME_CONTROL devName;

    PAGED_CODE();

    //
    //  The DeviceObject passed in is always the base device object at this
    //  point because it is the file system's control device object.  We can
    //  just query this object's name directly.
    //

⌨️ 快捷键说明

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