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

📄 filemon.c

📁 Socket异步通信示程序代码下载.非常直观
💻 C
📖 第 1 页 / 共 5 页
字号:
    // Look-up the entry
    //
    hashEntry = HashTable[ HASHOBJECT( fileObject ) ];
    prevEntry = NULL;

    while( hashEntry && hashEntry->FileObject != fileObject ) {

        prevEntry = hashEntry;
        hashEntry = hashEntry->Next;
    }
 
    //  
    // If we fall of the hash list without finding what we're looking
    // for, just return.
    //
    if( !hashEntry ) {

        KeReleaseSpinLock( &HashMutex, oldirql );
        return;
    }

    //
    // Got it! Remove it from the list
    //
    if( prevEntry ) {

        prevEntry->Next = hashEntry->Next;

    } else {

        HashTable[ HASHOBJECT( fileObject )] = hashEntry->Next;
    }

    //
    // Free the memory associated with the name of the free entry.
    //
    MemFreePool( hashEntry->FullPathName );
    MemFreeToNPagedLookasideList( &HashLookaside, hashEntry );

    KeReleaseSpinLock( &HashMutex, oldirql );
}

//----------------------------------------------------------------------
//       P A T H  A N D  P R O C E S S  N A M E  R O U T I N E S
//----------------------------------------------------------------------


//----------------------------------------------------------------------
//
// FilemonFreeFilters
//
// Fress storage we allocated for filter strings.
//
//----------------------------------------------------------------------
VOID FilemonFreeFilters()
{
    ULONG   i;
    
    for( i = 0; i < NumProcessFilters; i++ ) {

        MemFreePool( ProcessFilters[i] );
    }
    for( i = 0; i < NumProcessExcludeFilters; i++ ) {

        MemFreePool( ProcessExcludeFilters[i] );
    }
    for( i = 0; i < NumPathIncludeFilters; i++ ) {

        MemFreePool( PathIncludeFilters[i] );
    }
    for( i = 0; i < NumPathExcludeFilters; i++ ) {

        MemFreePool( PathExcludeFilters[i] );
    }
    NumProcessFilters = 0;
    NumProcessExcludeFilters = 0;
    NumPathIncludeFilters = 0;
    NumPathExcludeFilters = 0;
}

//----------------------------------------------------------------------
//
// MakeFilterArray
//
// Takes a filter string and splits into components (a component
// is seperated with a ';')
//
//----------------------------------------------------------------------
VOID MakeFilterArray( PCHAR FilterString,
                      PCHAR FilterArray[],
                      PULONG NumFilters )
{
    PCHAR filterStart;
    ULONG filterLength;

    //
    // Scan through the process filters
    //
    filterStart = FilterString;
    while( *filterStart ) {

        filterLength = 0;
        while( filterStart[filterLength] &&
               filterStart[filterLength] != ';' ) {

            filterLength++;
        }

        //
        // Ignore zero-length components
        //
        if( filterLength ) {

            FilterArray[ *NumFilters ] = 
                MemAllocatePool( NonPagedPool, filterLength + 1  );
            strncpy( FilterArray[ *NumFilters ],
                     filterStart, filterLength );
            FilterArray[ *NumFilters ][filterLength] = 0;
            (*NumFilters)++;
        }
    
        //
        // Are we done?
        //
        if( !filterStart[filterLength] ) break;

        //
        // Move to the next component (skip over ';')
        //
        filterStart += filterLength + 1;
    }
}


//----------------------------------------------------------------------
//
// FilemonUpdateFilters
//
// Takes a new filter specification and updates the filter
// arrays with them.
//
//----------------------------------------------------------------------
VOID FilemonUpdateFilters()
{
    KIRQL  oldirql;

    //
    // Free old filters (if any)
    //
    KeAcquireSpinLock( &FilterMutex, &oldirql );
    FilemonFreeFilters();

    //
    // Create new filter arrays
    //
    MakeFilterArray( FilterDef.processfilter,
                     ProcessFilters, &NumProcessFilters );
    MakeFilterArray( FilterDef.excludeprocess,
                     ProcessExcludeFilters, &NumProcessExcludeFilters );
    MakeFilterArray( FilterDef.pathfilter,
                     PathIncludeFilters, &NumPathIncludeFilters );
    MakeFilterArray( FilterDef.excludefilter,
                     PathExcludeFilters, &NumPathExcludeFilters );    

    KeReleaseSpinLock( &FilterMutex, oldirql );
}


//----------------------------------------------------------------------
//
// ApplyNameFilter
//
// If the name matches the exclusion mask, we do not log it. Else if
// it doesn't match the inclusion mask we do not log it. 
//
//----------------------------------------------------------------------
BOOLEAN ApplyNameFilter( PCHAR fullname )
{
    ULONG i;
    KIRQL oldirql;

    //
    // If no GUI or no filename return FALSE
    //
    if ( !fullname ) return FALSE;

    //   
    // If it matches the exclusion string, do not log it
    //
    KeAcquireSpinLock( &FilterMutex, &oldirql );
    for( i = 0; i < NumPathExcludeFilters; i++ ) {

        if( MatchWithPattern( PathExcludeFilters[i], fullname ) ) {

            KeReleaseSpinLock( &FilterMutex, oldirql );
            return FALSE;
        }
    }
 
    //
    // If it matches an include filter then log it
    //
    for( i = 0; i < NumPathIncludeFilters; i++ ) {

        if( MatchWithPattern( PathIncludeFilters[i], fullname )) {

            KeReleaseSpinLock( &FilterMutex, oldirql );
            return TRUE;
        }
    }

    //
    // It didn't match any include filters so don't log
    //
    KeReleaseSpinLock( &FilterMutex, oldirql );
    return FALSE;
}


//----------------------------------------------------------------------
//
// FilemonGetFullPath
//
// Takes a fileobject and filename and returns a canonical path,
// nicely formatted, in fullpathname.
//
//----------------------------------------------------------------------
VOID FilemonGetFullPath( PFILE_OBJECT fileObject, PHOOK_EXTENSION hookExt, 
                         PCHAR fullPathName )
{
    ULONG               pathLen;
    PCHAR               pathOffset;
    PFILE_OBJECT        relatedFileObject;
    PHASH_ENTRY         hashEntry, newEntry;
    ANSI_STRING         componentName;
    KIRQL               oldirql;

    //
    // Only do this if a GUI is active and filtering is on
    //
    if( !FilterOn || !hookExt || !fullPathName) {
     
        fullPathName[0] = 0;
        return;
    }

    //
    // First, lookup the object in the hash table to see if a name 
    // has already been generated for it
    //
    KeAcquireSpinLock( &HashMutex, &oldirql );

    hashEntry = HashTable[ HASHOBJECT( fileObject ) ];
    while( hashEntry && hashEntry->FileObject != fileObject )  {

        hashEntry = hashEntry->Next;
    }

    //
    // Did we find an entry?
    //
    if( hashEntry ) {

        //
        // Yes, so get the name from the entry.
        //
        strcpy( fullPathName, hashEntry->FullPathName );
        KeReleaseSpinLock( &HashMutex, oldirql );

        return;
    }

    KeReleaseSpinLock( &HashMutex, oldirql );

    //
    // We didn't find the name in the hash table, so we have to attempt
    // to construct it from the file objects.  Note that we won't always
    // be able to successfully do this, because the file system may
    // deallocate the name in the file object at its discretion. 
    //

    //
    // Is it DASD (Volume) I/O?
    //
    if( !fileObject || !fileObject->FileName.Length || fileObject->FileName.Length > 2*MAXPATHLEN ) {

        sprintf( fullPathName, "%C: DASD", hookExt->LogicalDrive );
        return;
    }
    
    //
    // Do this in an exception handling block, in case of mangled names in the
    // file object
    //
    try {

        //
        // Now, create the full path name. First, calculate the length taking into 
        // account space for seperators and the leading drive letter plus ':'
        //
        pathLen = fileObject->FileName.Length/2 + 2;

        relatedFileObject = fileObject->RelatedFileObject;
    
        //
        // Only look at related file object if this is a relative name
        //
        if( fileObject->FileName.Buffer[0] != L'\\' )  {

            while( relatedFileObject ) {
	        
                // 
                // If its too long, just stop.
                // 
    
                if( pathLen + relatedFileObject->FileName.Length/2+1 >= MAXPATHLEN ) {
 
                    break;
                }

                pathLen += relatedFileObject->FileName.Length/2+1;

                relatedFileObject = relatedFileObject->RelatedFileObject;
            }
    
        }

        //
        // Add the drive letter first at the front of the name
        //
        sprintf( fullPathName, "%C:", hookExt->LogicalDrive );
    
        //
        // Now, start at the end and work back to the beginning of the path
        //
        pathOffset = fullPathName + pathLen - fileObject->FileName.Length/2;

        RtlUnicodeStringToAnsiString( &componentName, &fileObject->FileName, TRUE );    

        strncpy( pathOffset, componentName.Buffer, componentName.Length + 1 );

        RtlFreeAnsiString( &componentName );

        relatedFileObject = fileObject->RelatedFileObject;
    
        if( fileObject->FileName.Buffer[0] != L'\\' )  {

            while( relatedFileObject ) {

                *(pathOffset - 1) = '\\';

                pathOffset -= relatedFileObject->FileName.Length/2 + 1;

                //
                // Bail when we've maxed the string.
                //

                if( pathOffset <= fullPathName ) {

                    break;
                }

                RtlUnicodeStringToAnsiString( &componentName, 
                                              &relatedFileObject->FileName, TRUE );

                strncpy( pathOffset, componentName.Buffer,
                         componentName.Length );

                RtlFreeAnsiString( &componentName );

                relatedFileObject = relatedFileObject->RelatedFileObject;
            }
        }  

        //
        // If we added two '\' to the front because there was a relative file object
        // that specified the root directory, remove one
        //
        if( pathLen > 3 && fullPathName[2] == '\\' && fullPathName[3] == '\\' )  {
        
            strcpy( fullPathName + 2, fullPathName + 3 );
        }

        //
        // If its a network drive, take off the first drive letter. This is because
        // network drives share a common device objects and the names are fully formed to 
        // specify the network mounted drive letter already
        //
        if( pathLen > 5 && fullPathName[4] == ':' && fullPathName[5] == '\\') {

            strcpy( fullPathName, fullPathName + 3 );
        }
    } except( EXCEPTION_EXECUTE_HANDLER ) {

        //
        // No name available - go with a dummy name
        //
        sprintf( fullPathName, "%C: ???", hookExt->LogicalDrive );
    }

    // 
    // Now that we have a name associated with the file object, put the
    // association in a hash table
    //
    KeAcquireSpinLock( &HashMutex, &oldirql );

    //
    // Allocate a hash entry
    //
    newEntry = MemAllocateFromNPagedLookasideList( &HashLookaside );

    //
    // If no memory for a new entry, oh well.
    //
    if( newEntry ) {

        //
        // Fill in the new entry and put it in the hash table
        //
        newEntry->FileObject 	= fileObject;

        newEntry->FullPathName	= MemAllocatePool( NonPagedPool, strlen(fullPathName)+1);

        //
        // Make sure there was memory for the name
        //
        if( !newEntry->FullPathName ) {

⌨️ 快捷键说明

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