📄 regmon.c
字号:
//======================================================================
//
// REGMON.c - main module for VxD REGMON
//
// Copyright(C) 1996-1999 Mark Russinovich and Bryce Cogswell
// Systems Internals - http://www.sysinternals.com
//
//======================================================================
#define DEVICE_MAIN
#include <vtoolsc.h>
#include "..\gui\ioctlcmd.h"
#include "regmon.h"
#undef DEVICE_MAIN
#if DEBUG
#define dprint(arg) dprintf arg
#else
#define dprint(arg)
#endif
//----------------------------------------------------------------------
// G L O B A L D A T A
//----------------------------------------------------------------------
//
// Real service pointers with the hook thunks
//
HDSC_Thunk ROKThunk;
LONG (*RealRegOpenKey)(HKEY, PCHAR, PHKEY );
HDSC_Thunk RCKThunk;
LONG (*RealRegCloseKey)(HKEY );
HDSC_Thunk RFKThunk;
LONG (*RealRegFlushKey)(HKEY );
HDSC_Thunk RCRKThunk;
LONG (*RealRegCreateKey)(HKEY, PCHAR, PHKEY );
HDSC_Thunk RDKThunk;
LONG (*RealRegDeleteKey)(HKEY, PCHAR );
HDSC_Thunk RDVThunk;
LONG (*RealRegDeleteValue)(HKEY, PCHAR );
HDSC_Thunk REKThunk;
LONG (*RealRegEnumKey)(HKEY, DWORD, PCHAR, DWORD );
HDSC_Thunk REVThunk;
LONG (*RealRegEnumValue)(HKEY, DWORD, PCHAR, PDWORD, PDWORD, PDWORD,
PBYTE, PDWORD );
HDSC_Thunk RQIKThunk;
LONG (*RealRegQueryInfoKey)(HKEY, PCHAR, PDWORD, DWORD, PDWORD, PDWORD,
PDWORD, PDWORD, PDWORD, PDWORD, PDWORD,
PFILETIME );
LONG (__stdcall *RealWin32RegQueryInfoKey)(PCLIENT_STRUCT, DWORD,
HKEY, PDWORD, PDWORD, PDWORD,
PDWORD, PDWORD );
HDSC_Thunk RQVThunk;
LONG (*RealRegQueryValue)( HKEY, PCHAR, PCHAR, PLONG );
HDSC_Thunk RQVEThunk;
LONG (*RealRegQueryValueEx)(HKEY, PCHAR, PDWORD, PDWORD, PBYTE, PDWORD );
HDSC_Thunk RSVThunk;
LONG (*RealRegSetValue)( HKEY, PCHAR, DWORD, PCHAR, DWORD );
HDSC_Thunk RSVEThunk;
LONG (*RealRegSetValueEx)(HKEY, PCHAR, DWORD, DWORD, PBYTE, DWORD );
HDSC_Thunk RRPDKThunk;
LONG (*RealRegRemapPreDefKey)(HKEY, HKEY );
HDSC_Thunk RQMVThunk;
LONG (*RealRegQueryMultipleValues)(HKEY, PVALENT, DWORD, PCHAR, PDWORD );
HDSC_Thunk RCDKThunk;
LONG (*RealRegCreateDynKey)( PCHAR, PVOID, PVOID, PVOID, DWORD, PVMMHKEY);
//
// Indicates if the GUI wants activity to be logged
//
BOOLEAN FilterOn = FALSE;
//
// Global filter (sent to us by the GUI)
//
FILTER FilterDef;
//
// 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];
//
// Hash table data
//
PHASH_ENTRY HashTable[NUMHASH];
//
// List of freed entries (to save some allocation calls)
//
PHASH_ENTRY FreeEntries = NULL;
//
// Buffer data
//
PSTORE_BUF Store = NULL;
ULONG Sequence = 0;
//
// Maximum amount of buffers we will grab for buffered unread data
//
ULONG NumStore = 0;
ULONG MaxStore = 5;
//
// Semaphore for critical sections
//
SEMHANDLE StoreMutex, HashMutex, FilterMutex;
//
// Unknown error string
//
CHAR errstring[32];
//
// VMM's Win32 service table (at least one Win32 registry
// call gets routed through here, bypassing the
// standard VMM VxD service entry points!)
//
PDWORD VMMWin32ServiceTable;
//----------------------------------------------------------------------
// V X D C O N T R O L
//----------------------------------------------------------------------
//
// Device declaration
//
Declare_Virtual_Device(REGMON)
//
// Message handlers - we only care about dynamic loading and unloading
//
DefineControlHandler(SYS_DYNAMIC_DEVICE_INIT, OnSysDynamicDeviceInit);
DefineControlHandler(SYS_DYNAMIC_DEVICE_EXIT, OnSysDynamicDeviceExit);
DefineControlHandler(W32_DEVICEIOCONTROL, OnW32Deviceiocontrol);
//----------------------------------------------------------------------
//
// ControlDispatcher
//
// Multiplexes incoming VxD messages from Windows to their handlers.
//
//----------------------------------------------------------------------
BOOL __cdecl ControlDispatcher(
DWORD dwControlMessage,
DWORD EBX,
DWORD EDX,
DWORD ESI,
DWORD EDI,
DWORD ECX)
{
START_CONTROL_DISPATCH
ON_SYS_DYNAMIC_DEVICE_INIT(OnSysDynamicDeviceInit);
ON_SYS_DYNAMIC_DEVICE_EXIT(OnSysDynamicDeviceExit);
ON_W32_DEVICEIOCONTROL(OnW32Deviceiocontrol);
END_CONTROL_DISPATCH
return TRUE;
}
//----------------------------------------------------------------------
// 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 U F F E R M A N A G E M E N T A N D P R I N T R O U T I N E S
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// RegmonFreeStore
//
// Frees all the data output buffers that we have currently allocated.
//
//----------------------------------------------------------------------
VOID RegmonFreeStore()
{
PSTORE_BUF prev;
//
// Just traverse the list of allocated output buffers
//
while( Store ) {
prev = Store->Next;
PageFree( (MEMHANDLE) Store, 0 );
Store = prev;
}
}
//----------------------------------------------------------------------
//
// RegmonNewStore
//
// Called when the current buffer has filled up. This moves us to the
// pre-allocated buffer and then allocates another buffer.
//
//----------------------------------------------------------------------
void RegmonNewStore( void )
{
PSTORE_BUF prev = Store, newstore;
//
// If we have maxed out or haven't accessed the current store
// just return.
//
if( MaxStore == NumStore ) {
Store->Len = 0;
return;
}
//
// If the output buffer we currently are using is empty, just
// use it.
//
if( !Store->Len )
return;
//
// Allocate a new output buffer
//
PageAllocate(STORESIZE, PG_SYS, 0, 0, 0, 0, NULL, PAGELOCKED,
(PMEMHANDLE) &newstore, (PVOID) &newstore );
if( newstore ) {
//
// Allocation was successful so add the buffer to the list
// of allocated buffers and increment the buffer count.
//
Store = newstore;
Store->Len = 0;
Store->Next = prev;
NumStore++;
} else {
//
// The allocation failed - just reuse the current buffer
//
Store->Len = 0;
}
}
//----------------------------------------------------------------------
//
// RegmonOldestStore
//
// Goes through the linked list of storage buffers and returns the
// oldest one.
//
//----------------------------------------------------------------------
PSTORE_BUF RegmonOldestStore( void )
{
PSTORE_BUF ptr = Store, prev = NULL;
//
// Traverse the list
//
while ( ptr->Next ) {
ptr = (prev = ptr)->Next;
}
//
// Remove the buffer from the list
//
if ( prev ) {
prev->Next = NULL;
}
NumStore--;
return ptr;
}
//----------------------------------------------------------------------
//
// RegmonResetStore
//
// When a GUI is no longer communicating with us, but we can't unload,
// we reset the storage buffers.
//
//----------------------------------------------------------------------
VOID RegmonResetStore()
{
PSTORE_BUF current, next;
//
// Traverse the list of output buffers
//
current = Store->Next;
while( current ) {
//
// Free the buffer
//
next = current->Next;
PageFree( (MEMHANDLE) current, 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -