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

📄 regsys.c

📁 一个完整的注册表监视器
💻 C
📖 第 1 页 / 共 5 页
字号:
//======================================================================
// 
// Regsys.c
//
// Copyright (C) 1996-1998 Mark Russinovich and Bryce Cogswell
//
// Hooks the registry by replacing registry related calls in the system
// service table with pointers to our own hook routines. Very simple
// yet very effective.
//
//======================================================================
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"
#include "..\gui\ioctlcmd.h"
#include "regsys.h"

//----------------------------------------------------------------------
//                           DEFINES
//----------------------------------------------------------------------
// print macro that only turns on when debugging is on
#if DBG
#define DbgPrint(arg) DbgPrint arg
#else
#define DbgPrint(arg) 
#endif

//
// Macro for easy hook/unhook. On X86 implementations of Zw* functions, the DWORD
// following the first byte is the system call number, so we reach into the Zw function
// passed as a parameter, and pull the number out. This makes system call hooking
// dependent ONLY on the Zw* function implementation not changing.
//

#if defined(_ALPHA_)
#define SYSCALL(_function)  ServiceTable->ServiceTable[ (*(PULONG)_function)  & 0x0000FFFF ]
#else
#define SYSCALL(_function)  ServiceTable->ServiceTable[ *(PULONG)((PUCHAR)_function+1)]
#endif

//
// Number of predefined rootkeys
//
#define NUMROOTKEYS     4


//
// The name of the System process, in which context we're called in our DriverEntry
//
#define SYSNAME         "System"

//
// A unicode string constant for the "default" value
//
#define DEFAULTNAMELEN  (9*sizeof(WCHAR))
WCHAR                   DefaultValueString[] = L"(Default)";
UNICODE_STRING          DefaultValue = {
    DEFAULTNAMELEN,
    DEFAULTNAMELEN,
    DefaultValueString
};

//
// A filter to use if we're monitoring boot activity
//
FILTER  BootFilter = {
    "*", "", "*", "",
    TRUE, TRUE, TRUE, TRUE 
};

//----------------------------------------------------------------------
//                         FORWARD DEFINES
//---------------------------------------------------------------------- 
NTSTATUS RegmonDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
VOID     RegmonUnload( IN PDRIVER_OBJECT DriverObject );

//----------------------------------------------------------------------
//                         GLOBALS
//---------------------------------------------------------------------- 
// our user-inteface device object
PDEVICE_OBJECT          GUIDevice;

//
// Is a GUI talking to us?
//
BOOLEAN                 GUIActive = FALSE;

//
// Are we logging a boot sequence?
//
BOOLEAN                 BootLogging = FALSE;
KEVENT                  LoggingEvent;
HANDLE                  LogFile = INVALID_HANDLE_VALUE;
PSTORE_BUF              BootSavedStoreList = NULL;
PSTORE_BUF              BootSavedStoreTail;

//
// Is registry hooked?
//
BOOLEAN                 RegHooked = FALSE;

//
// Global error string
//
CHAR                    errstring[256];

//
// Global filter (sent to us by the GUI)
//
FILTER                  FilterDef;

//
// Lock to protect filter arrays
//
KMUTEX                  FilterMutex;

//
// Array of process and path filters 
//
ULONG                   NumProcessFilters = 0;
PCHAR                   ProcessFilters[MAXFILTERS];
ULONG                   NumProcessExcludeFilters = 0;
PCHAR                   ProcessExcludeFilters[MAXFILTERS];
ULONG                   NumPathIncludeFilters = 0;
PCHAR                   PathIncludeFilters[MAXFILTERS];
ULONG                   NumPathExcludeFilters = 0;
PCHAR                   PathExcludeFilters[MAXFILTERS];

//
// Pointer to system global service table
//
PSRVTABLE               ServiceTable;

//
// This is the offset into a KPEB of the current process name. This is determined
// dynamically by scanning the process block belonging to the GUI for its name.
//
ULONG                   ProcessNameOffset;

//
// We save off pointers to the actual Registry functions in these variables
//
NTSTATUS (*RealRegOpenKey)( IN PHANDLE, IN OUT ACCESS_MASK, IN POBJECT_ATTRIBUTES );
NTSTATUS (*RealRegQueryKey)( IN HANDLE, IN KEY_INFORMATION_CLASS,
                             OUT PVOID, IN ULONG, OUT PULONG );
NTSTATUS (*RealRegQueryValueKey)( IN HANDLE, IN PUNICODE_STRING, 
                                  IN KEY_VALUE_INFORMATION_CLASS,
                                  OUT PVOID, IN ULONG, OUT PULONG );
NTSTATUS (*RealRegEnumerateValueKey)( IN HANDLE, IN ULONG,  
                                      IN KEY_VALUE_INFORMATION_CLASS,
                                      OUT PVOID, IN ULONG, OUT PULONG );
NTSTATUS (*RealRegEnumerateKey)( IN HANDLE, IN ULONG,
                                 IN KEY_INFORMATION_CLASS,
                                 OUT PVOID, IN ULONG, OUT PULONG );
NTSTATUS (*RealRegSetValueKey)( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName,
                                IN ULONG TitleIndex, IN ULONG Type, 
                                IN PVOID Data, IN ULONG DataSize );
NTSTATUS (*RealRegCreateKey)( OUT PHANDLE, IN ACCESS_MASK,
                              IN POBJECT_ATTRIBUTES , IN ULONG,
                              IN PUNICODE_STRING, IN ULONG, OUT PULONG );
NTSTATUS (*RealRegDeleteValueKey)( IN HANDLE, IN PUNICODE_STRING );
NTSTATUS (*RealRegCloseKey)( IN HANDLE );
NTSTATUS (*RealRegDeleteKey)( IN HANDLE );
NTSTATUS (*RealRegFlushKey)( IN HANDLE );

//
// Lenghs of rootkeys (filled in at init). This table allows us to translate 
// path names into better-known forms. Current user is treated specially since
// its not a full match.
//
ROOTKEY CurrentUser[2] = {
    { "\\\\REGISTRY\\USER\\S", "HKCU", 0 },
    { "HKU\\S", "HKCU", 0 }
};

ROOTKEY RootKey[NUMROOTKEYS] = {
    { "\\\\REGISTRY\\USER", "HKU", 0 },
    { "\\\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\HARDWARE PROFILES\\CURRENT", 
      "HKCC", 0 },
    { "\\\\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES", "HKCR", 0 },
    { "\\\\REGISTRY\\MACHINE", "HKLM", 0 }
};

//
// This is a hash table for keeping names around for quick lookup.
//
PHASH_ENTRY             HashTable[NUMHASH];

//
// Mutex for hash table accesses
//
KMUTEX                  HashMutex;

//
// Data structure for storing messages we generate
//
PSTORE_BUF              Store           = NULL;
ULONG                   Sequence        = 0;
KMUTEX                  StoreMutex;

//
// Maximum amount of data we will grab for buffered unread data
//
ULONG                   NumStore        = 0;
ULONG                   MaxStore        = MAXMEM/MAX_STORE;

//
// Free hash list. Note: we don't use lookaside lists since
// we want to be able to run on NT 3.51 - lookasides were
// introduced in NT 4.0
//
PHASH_ENTRY             FreeHashList = NULL;


//======================================================================
//      P A T T E R N   M A T C H I N G   R O U T I N E S
//======================================================================


//----------------------------------------------------------------------
//
// MatchOkay
//
// Only thing left after compare is more mask. This routine makes
// sure that its a valid wild card ending so that its really a match.
//
//----------------------------------------------------------------------
BOOLEAN MatchOkay( PCHAR Pattern )
{
    //
    // If pattern isn't empty, it must be a wildcard
    //
    if( *Pattern && *Pattern != '*' ) {
 
        return FALSE;
    }

    //
    // Matched
    //
    return TRUE;
}



//----------------------------------------------------------------------
//
// MatchWithPattern
//
// Performs nifty wildcard comparison.
//
//----------------------------------------------------------------------
BOOLEAN MatchWithPattern( PCHAR Pattern, PCHAR Name )
{
    CHAR   upcase;

    //
    // End of pattern?
    //
    if( !*Pattern ) {

        return FALSE;
    }

    //
    // If we hit a wild card, do recursion
    //
    if( *Pattern == '*' ) {

        Pattern++;

        while( *Name && *Pattern ) {

            if( *Name >= 'a' && *Name <= 'z' )
                upcase = *Name - 'a' + 'A';
            else
                upcase = *Name;

            //
            // See if this substring matches
            //
            if( *Pattern == upcase || *Name == '*' ) {

                if( MatchWithPattern( Pattern+1, Name+1 )) {

                    return TRUE;
                }
            }

            //
            // Try the next substring
            //
            Name++;
        }

        //
        // See if match condition was met
        //
        return MatchOkay( Pattern );
    } 

    //
    // Do straight compare until we hit a wild card
    //
    while( *Name && *Pattern != '*' ) {

        if( *Name >= 'a' && *Name <= 'z' )
            upcase = *Name - 'a' + 'A';
        else
            upcase = *Name;

        if( *Pattern == upcase ) {

            Pattern++;
            Name++;

        } else {

            return FALSE;
        }
    }

    //
    // If not done, recurse
    //
    if( *Name ) {

        return MatchWithPattern( Pattern, Name );
    }

    //
    // Make sure its a match
    //
    return MatchOkay( Pattern );
}

//======================================================================
//       B O O T   L O G G I N G   W O R K   R O U T I N E S
//======================================================================

//----------------------------------------------------------------------
//
// RegmonOpenBootLog
//
// Open a log file.
//
//----------------------------------------------------------------------
NTSTATUS RegmonOpenBootLog()
{
    WCHAR                   logFileNameBuffer[] =  L"\\SystemRoot\\REGMON.LOG";
    UNICODE_STRING          logFileUnicodeString;
    OBJECT_ATTRIBUTES       objectAttributes;
    IO_STATUS_BLOCK         ioStatus;
    NTSTATUS                ntStatus;

    RtlInitUnicodeString( &logFileUnicodeString, logFileNameBuffer );
    InitializeObjectAttributes( &objectAttributes, &logFileUnicodeString,
                                OBJ_CASE_INSENSITIVE, NULL, NULL );

    ntStatus = ZwCreateFile( &LogFile, FILE_WRITE_DATA|SYNCHRONIZE,
                             &objectAttributes, &ioStatus, NULL, 
                             FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
                             FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );
    return ntStatus;
}

//----------------------------------------------------------------------
//
// RegmonCloseBootLog - worker thread routine
//
// Close the boot log file.
//
//----------------------------------------------------------------------
VOID RegmonCloseBootLog( PVOID Context )
{
    ZwClose( LogFile );
    KeSetEvent( &LoggingEvent, 0, FALSE );
    LogFile = INVALID_HANDLE_VALUE;
}

//----------------------------------------------------------------------
//
// RegmonWriteBuffer
//
// Dumps a buffer to the log file.
//
//----------------------------------------------------------------------
VOID RegmonWriteBuffer( PSTORE_BUF LogStore )
{
    ULONG       len;
    ULONG       itemcnt;
    UCHAR       seqtext[64];
    static CHAR diskFullError[] = "Not enough disk space for log file\n"; 
    PCHAR       textptr, items[10];
    PENTRY      entry;
    FILE_END_OF_FILE_INFORMATION zeroLengthFile;
    IO_STATUS_BLOCK ioStatus;

    //
    // Process the buffer
    //
    for( entry = (PENTRY) LogStore->Data; entry < (PENTRY) ((PCHAR) LogStore + LogStore->Len); ) {
        
        len = strlen( entry->text );
        len += 4; len &= 0xFFFFFFFC;
        
        //
        // Write out the entry. 
        //
        sprintf( seqtext, "%d: ", entry->seq );
        ZwWriteFile( LogFile, NULL, NULL, NULL, &ioStatus,
                     seqtext, strlen(seqtext), NULL, NULL );        
        ZwWriteFile( LogFile, NULL, NULL, NULL, &ioStatus,
                     entry->text, strlen(entry->text), NULL, NULL );
        ZwWriteFile( LogFile, NULL, NULL, NULL, &ioStatus,
                     "\n\r", strlen("\n\r"), NULL, NULL );
            
        //
        // If the disk is full, delete the log file

⌨️ 快捷键说明

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