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

📄 filemon.c

📁 Socket异步通信示程序代码下载.非常直观
💻 C
📖 第 1 页 / 共 5 页
字号:
            MemFreeToNPagedLookasideList( &HashLookaside, newEntry );

        } else {

            newEntry->Next = HashTable[ HASHOBJECT(fileObject) ];
            HashTable[ HASHOBJECT(fileObject) ] = newEntry;	
            strcpy( newEntry->FullPathName, fullPathName );
        }
    }
    KeReleaseSpinLock( &HashMutex, oldirql );
}


//----------------------------------------------------------------------
//
// FilemonGetProcessNameOffset
//
// In an effort to remain version-independent, rather than using a
// hard-coded into the KPEB (Kernel Process Environment Block), we
// scan the KPEB looking for the name, which should match that
// of the system process. This is because we are in the system process'
// context in DriverEntry, where this is called.
//
//----------------------------------------------------------------------
ULONG FilemonGetProcessNameOffset()
{
    PEPROCESS       curproc;
    int             i;

    curproc = PsGetCurrentProcess();

    //
    // Scan for 12KB, hoping the KPEB never grows that big!
    //
    for( i = 0; i < 3*PAGE_SIZE; i++ ) {
     
        if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {

            return i;
        }
    }

    //
    // Name not found - oh, well
    //
    return 0;
}


//----------------------------------------------------------------------
//
// FilemonGetProcess
//
// Uses undocumented data structure offsets to obtain the name of the
// currently executing process.
//
//----------------------------------------------------------------------
PCHAR FilemonGetProcess( PCHAR Name )
{
#if GETPROCESS
    PEPROCESS       curproc;
    char            *nameptr;
    ULONG           i;
    KIRQL           oldirql;

    //
    // We only do this if we determined the process name offset
    //
    if( ProcessNameOffset ) {
      
        //
        // Get a pointer to the current process block
        //
        curproc = PsGetCurrentProcess();

        //
        // Dig into it to extract the name 
        //
        nameptr   = (PCHAR) curproc + ProcessNameOffset;
         
        strncpy( Name, nameptr, NT_PROCNAMELEN );

        //
        // Terminate in case process name overflowed
        //
        Name[NT_PROCNAMELEN] = 0;

    } else {

        strcpy( Name, "???" );
    }

    //
    // Apply process name filters
    //
    KeAcquireSpinLock( &FilterMutex, &oldirql );
    for( i = 0; i < NumProcessExcludeFilters; i++ ) {

        if( MatchWithPattern( ProcessExcludeFilters[i], Name )) {

            KeReleaseSpinLock( &FilterMutex, oldirql );
            return NULL;
        }
    }
    for( i = 0; i < NumProcessFilters; i++ ) {

        if( MatchWithPattern( ProcessFilters[i], Name ) ) {

            KeReleaseSpinLock( &FilterMutex, oldirql );
            return Name;
        }
    }
    KeReleaseSpinLock( &FilterMutex, oldirql );
    return NULL;
#else

    //
    // We're not getting names, so just return something
    //
    strcpy( Name, "??" );

    return Name;
#endif
}


//----------------------------------------------------------------------
//          H O O K / U N H O O K   R O U T I N E S
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//
// HookDrive
//
// Hook the drive specified by determining which device object to 
// attach to. The algorithm used here is similar to the one used
// internally by NT to determine which device object a file system request
// is directed at.
//
//----------------------------------------------------------------------
BOOLEAN HookDrive( IN char Drive, IN PDRIVER_OBJECT DriverObject )
{
    IO_STATUS_BLOCK     ioStatus;
    HANDLE              ntFileHandle;   
    OBJECT_ATTRIBUTES   objectAttributes;
    PDEVICE_OBJECT      fileSysDevice;
    PDEVICE_OBJECT      hookDevice;
    UNICODE_STRING      fileNameUnicodeString;
    WCHAR               filename[] = L"\\DosDevices\\A:\\";
    NTSTATUS            ntStatus;
    ULONG               i;
    PFILE_OBJECT        fileObject;
    PHOOK_EXTENSION     hookExtension;
    
    //
    // Translate the drive letter to a 0-based integer
    //
    if ( Drive >= 'a' && Drive <= 'z' ) {

        Drive -= 'a';

    } else {

        Drive -= 'A';

    }

    //
    // Is it a legal drive letter?
    //
    if ( (unsigned char) Drive >= 26 )  {

        return FALSE;
    }

    //
    // Has this drive already been hooked?
    //
    if ( LDriveDevices[Drive] == NULL )  {

        //
        // Frob the name to make it refer to the drive specified in the input 
        // parameter.
        //
        filename[12] = 'A'+Drive;

        //
        // We have to figure out what device to hook - first open the volume's 
        // root directory
        //
        RtlInitUnicodeString( &fileNameUnicodeString, filename );
        InitializeObjectAttributes( &objectAttributes, &fileNameUnicodeString, 
                                    OBJ_CASE_INSENSITIVE, NULL, NULL );
        ntStatus = ZwCreateFile( &ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS, 
                                 &objectAttributes, &ioStatus, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 
                                 FILE_OPEN, 
                                 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, 
                                 NULL, 0 );
        if( !NT_SUCCESS( ntStatus ) ) {

            DbgPrint(("Filemon: Could not open drive %c: %x\n", 'A'+Drive, ntStatus ));

            return FALSE;
        }

        DbgPrint(("Filemon:  opened the root directory!!! handle: %x\n", ntFileHandle));   

        //
        // Got the file handle, so now look-up the file-object it refers to
        //
        ntStatus = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA, 
                                              NULL, KernelMode, &fileObject, NULL );
        if( !NT_SUCCESS( ntStatus )) {

            DbgPrint(("Filemon: Could not get fileobject from handle: %c\n", 'A'+Drive ));
            ZwClose( ntFileHandle );

            return FALSE;
        }

        //  
        // Next, find out what device is associated with the file object by getting its related
        // device object
        //
        fileSysDevice = IoGetRelatedDeviceObject( fileObject );

        if ( ! fileSysDevice ) {

            DbgPrint(("Filemon: Could not get related device object: %c\n", 'A'+Drive ));

            ObDereferenceObject( fileObject );
            ZwClose( ntFileHandle );

            return FALSE;
        }

        //  
        // Check the device list to see if we've already attached to this particular device. 
        // This can happen when more than one drive letter is being handled by the same network
        // redirecter
        //  
        for( i = 0; i < 26; i++ ) {

            if( LDriveDevices[i] == fileSysDevice ) {

                //
                // If we're already watching it, associate this drive letter
                // with the others that are handled by the same network driver. This
                // enables us to intelligently update the hooking menus when the user
                // specifies that one of the group should not be watched -we mark all
                // of the related drives as unwatched as well
                //
                ObDereferenceObject( fileObject );

                ZwClose( ntFileHandle );

                LDriveMap[ Drive ]     = LDriveMap[i];
                LDriveDevices[ Drive ] = fileSysDevice;

                return TRUE;
            }
        }

        //
        // The file system's device hasn't been hooked already, so make a hooking device
        //  object that will be attached to it.
        //
        ntStatus = IoCreateDevice( DriverObject,
                                   sizeof(HOOK_EXTENSION),
                                   NULL,
                                   fileSysDevice->DeviceType,
                                   0,
                                   FALSE,
                                   &hookDevice );
        if ( !NT_SUCCESS(ntStatus) ) {

            DbgPrint(("Filemon: failed to create associated device: %c\n", 'A'+Drive ));   

            ObDereferenceObject( fileObject );
            ZwClose( ntFileHandle );

            return FALSE;
        }

        //
        // Clear the device's init flag as per NT DDK KB article on creating device 
        // objects from a dispatch routine
        //
        hookDevice->Flags &= ~DO_DEVICE_INITIALIZING;

        //
        // Setup the device extensions. The drive letter and file system object are stored
        // in the extension.
        //
        hookExtension = hookDevice->DeviceExtension;
        hookExtension->LogicalDrive = 'A'+Drive;
        hookExtension->FileSystem   = fileSysDevice;

        //
        // Finally, attach to the device. The second we're successfully attached, we may 
        // start receiving IRPs targetted at the device we've hooked.
        //
        ntStatus = IoAttachDeviceByPointer( hookDevice, fileSysDevice );
        if ( !NT_SUCCESS(ntStatus) )  {

            //
            // Couldn' attach for some reason
            //
            DbgPrint(("Filemon: Connect with Filesystem failed: %c (%x) =>%x\n", 
                      'A'+Drive, fileSysDevice, ntStatus ));

            //
            // Derefence the object and get out
            //
            ObDereferenceObject( fileObject );
            ZwClose( ntFileHandle );

            return FALSE;

        } else {

            // 
            // Make a new drive group for the device,l if it does not have one 
            // already
            // 
            DbgPrint(("Filemon: Successfully connected to Filesystem device %c\n", 'A'+Drive ));
            if( !LDriveMap[ Drive ] ) {

                LDriveMap[ Drive ] = ++LDriveGroup;
            }
        }
    
        //
        // Close the file and update the hooked drive list by entering a
        // pointer to the hook device object in it.
        //
        ObDereferenceObject( fileObject );

        ZwClose( ntFileHandle );

        LDriveDevices[Drive] = hookDevice;
    }

    return TRUE;
}


//----------------------------------------------------------------------
//
// UnhookDrive
//
// Unhook a previously hooked drive.
//
//----------------------------------------------------------------------
BOOLEAN UnhookDrive( IN char Drive )
{
    PHOOK_EXTENSION hookExt;

    //
    // Translate the drive letter to a 0-based integer
    //
    if ( Drive >= 'a' && Drive <= 'z' ) {

        Drive -= 'a';

    } else {

        Drive -= 'A';

    }

    //
    // If the drive has been hooked, unhook it and delete the hook
    // device object
    //
    if ( LDriveDevices[Drive] )  {

        hookExt = LDriveDevices[Drive]->DeviceExtension;

        IoDetachDevice( hookExt->FileSystem );

        IoDeleteDevice( LDriveDevices[Drive] );

        LDriveDevices[Drive] = NULL;
    }
    return TRUE;
}


//----------------------------------------------------------------------
//
// HookDriveSet
//
// Hook/Unhook a set of drives specified by user. Return the set 
// that is currently hooked.
//
//----------------------------------------------------------------------
ULONG HookDriveSet( IN ULONG DriveSet, IN PDRIVER_OBJECT DriverObject )
{
    ULONG drive, i;
    ULONG bit;

    //
    // Scan the drive table, looking for hits on the DriveSet bitmask
    //
    for ( drive = 0; drive < 26; ++drive )  {

        bit = 1 << drive;

        //
        // Are we suppoed to hook this drive?
        //
        if ( bit & DriveSet )  {

            //
            // Try to hook drive 
            //
            if ( ! HookDrive( (char)('A'+drive), DriverObject ) ) {
             
                //
                // Remove from drive set if can't be hooked
                //
                DriveSet &= ~bit;

            } else {

                //
                // hook drives in same drive group      

⌨️ 快捷键说明

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