📄 filemon.c
字号:
//======================================================================
//
// Filemon.c
//
// Copyright (C) 1996-1998 Mark Russinovich and Bryce Cogswell
//
// Implements the equivalent of Windows 95 IFSMgr_FileSystemApiHook.
//
//======================================================================
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"
#include "ioctlcmd.h"
#include "filemon.h"
#include "winioctl.h"
#include "memtrack.h"
//----------------------------------------------------------------------
// DEFINES
//----------------------------------------------------------------------
//
// Set this to 0 to make a processor-independent version that does
// not print out the process name
//
#define GETPROCESS 1
//
// Set this to 0 so that this driver can be built with pre-NT 5.0
// versions of the SDK
//
#define NT5_IOCTLS 1
//
// Print macro that only turns on when debugging is on
//
#if DBG
#define DbgPrint(arg) DbgPrint arg
#else
#define DbgPrint(arg)
#endif
//
// The name of the System process, in which context we're called in our DriverEntry
//
#define SYSNAME "System"
//----------------------------------------------------------------------
// TYPEDEFS
//----------------------------------------------------------------------
//
// Directory control structure
//
typedef struct {
ULONG Length;
PUNICODE_STRING FileName;
FILE_INFORMATION_CLASS FileInformationClass;
ULONG FileIndex;
} QUERY_DIRECTORY, *PQUERY_DIRECTORY;
//
// Lock control data structure
//
typedef struct {
PLARGE_INTEGER Length;
ULONG Key;
LARGE_INTEGER ByteOffset;
} LOCK_CONTROL, *PLOCK_CONTROL;
//----------------------------------------------------------------------
// FORWARD DEFINES
//----------------------------------------------------------------------
NTSTATUS FilemonDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
VOID FilemonUnload( IN PDRIVER_OBJECT DriverObject );
//
// These are prototypes for Filemon's Fast I/O hooks. The originals
// prototypes can be found in NTDDK.H
//
BOOLEAN FilemonFastIoCheckifPossible( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoRead( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoWrite( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoQueryBasicInfo( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoQueryStandardInfo( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
OUT PFILE_STANDARD_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoLock( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key,
BOOLEAN FailImmediately, BOOLEAN ExclusiveLock,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoUnlockSingle( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoUnlockAll( IN PFILE_OBJECT FileObject, PEPROCESS ProcessId,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoUnlockAllByKey( IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoDeviceControl( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
IN PVOID InputBuffer, IN ULONG InputBufferLength,
OUT PVOID OutbufBuffer, IN ULONG OutputBufferLength, IN ULONG IoControlCode,
OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
VOID FilemonFastIoAcquireFile( PFILE_OBJECT FileObject );
VOID FilemonFastIoReleaseFile( PFILE_OBJECT FileObject );
VOID FilemonFastIoDetachDevice( PDEVICE_OBJECT SourceDevice, PDEVICE_OBJECT TargetDevice );
//
// These are new NT 4.0 Fast I/O calls
//
BOOLEAN FilemonFastIoQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait, OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer,
OUT struct _IO_STATUS_BLOCK *IoStatus, IN PDEVICE_OBJECT DeviceObject );
NTSTATUS FilemonFastIoAcquireForModWrite( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER EndingOffset, OUT struct _ERESOURCE **ResourceToRelease,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoMdlRead( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length,
IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoMdlReadComplete( IN PFILE_OBJECT FileObject,
IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoPrepareMdlWrite( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey,
OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoMdlWriteComplete( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoReadCompressed( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length,
IN ULONG LockKey, OUT PVOID Buffer, OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus,
OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo,
IN ULONG CompressedDataInfoLength, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoWriteCompressed( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN ULONG Length,
IN ULONG LockKey, IN PVOID Buffer, OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus,
IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo,
IN ULONG CompressedDataInfoLength, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoMdlReadCompleteCompressed( IN PFILE_OBJECT FileObject,
IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoMdlWriteCompleteCompressed( IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject );
BOOLEAN FilemonFastIoQueryOpen( IN struct _IRP *Irp,
OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
IN PDEVICE_OBJECT DeviceObject );
NTSTATUS FilemonFastIoReleaseForModWrite( IN PFILE_OBJECT FileObject,
IN struct _ERESOURCE *ResourceToRelease, IN PDEVICE_OBJECT DeviceObject );
NTSTATUS FilemonFastIoAcquireForCcFlush( IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject );
NTSTATUS FilemonFastIoReleaseForCcFlush( IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject );
//----------------------------------------------------------------------
// GLOBALS
//----------------------------------------------------------------------
//
// This is Filemon's user-inteface device object. It is addressed
// by calls from the GUI including CreateFile and DeviceIoControl
//
PDEVICE_OBJECT GUIDevice;
//
// Indicates if the GUI wants activity to be logged
//
BOOLEAN FilterOn = FALSE;
//
// Global filter (sent to us by the GUI)
//
FILTER FilterDef;
//
// This lock protects access to the filter array
//
KSPIN_LOCK 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];
//
// Which type of timing are we doing (told to us by GUI)
//
BOOLEAN TimeIsDuration;
//
// Once a load is initiated, this flag prevents the processing of
// further IRPs. This is required because an unload can only take
// place if there are any IRP's for which an IoCompletion has
// been registered that has not actually completed.
//
BOOLEAN UnloadInProgress = FALSE;
//
// 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 the name
// of the system process, in who's context we execute in DriverEntry
//
ULONG ProcessNameOffset;
//
// This variable keeps track of the outstanding IRPs (ones for which
// a completion routine has been registered, but that have not yet
// passed through the completion routine), which is used in
// the unload determination logic. The CountMutex protects data
// races on updating the count.
//
ULONG OutstandingIRPCount = 0;
KSPIN_LOCK CountMutex;
//
// Table of our hook devices for each drive letter. This makes it
// easy to look up the device object that was created to hook a
// particular drive.
//
PDEVICE_OBJECT LDriveDevices[26];
//
// This table keeps track of which drives are controlled by common
// network redirectors (unhooking one results in all of the group
// being unhooked). Each device object that is hooked is assigned
// a unique identifier. Network devices are used to represent
// multiple logical drives, so the drive map entries for network
// drive handled by the same network device object have the
// same identifier.
//
int LDriveMap[26];
int LDriveGroup = 0;
//
// Hash table for keeping names around. This is necessary because
// at any time the name information in the fileobjects that we
// see can be deallocated and reused. If we want to print accurate
// names, we need to keep them around ourselves.
//
PHASH_ENTRY HashTable[NUMHASH];
//
// Mutex to protect hash table.
//
KSPIN_LOCK HashMutex;
//
// The current output buffer
//
PSTORE_BUF Store = NULL;
//
// Each IRP is given a sequence number. This allows the return status
// of an IRP, which is obtained in the completion routine, to be
// associated with the IRPs parameters that were extracted in the Dispatch
// routine.
//
ULONG Sequence = 0;
//
// This mutex protects the output buffer
//
KSPIN_LOCK StoreMutex;
//
// Filemon keeps track of the number of distinct output buffers that
// have been allocated, but not yet uploaded to the GUI, and caps
// the amount of memory (which is in non-paged pool) it takes at
// 1MB.
//
ULONG NumStore = 0;
ULONG MaxStore = 1000000/MAX_STORE;
//
// Lookaside lists. One for hash entries and one for pathnames
//
NPAGED_LOOKASIDE_LIST HashLookaside;
NPAGED_LOOKASIDE_LIST PathLookaside;
//
// These are the text representations of the classes of IRP_MJ_SET/GET_INFORMATION
// calls
//
CHAR *FileInformation[] = {
"",
"FileDirectoryInformation",
"FileFullDirectoryInformation",
"FileBothDirectoryInformation",
"FileBasicInformation",
"FileStandardInformation",
"FileInternalInformation",
"FileEaInformation",
"FileAccessInformation",
"FileNameInformation",
"FileRenameInformation",
"FileLinkInformation",
"FileNamesInformation",
"FileDispositionInformation",
"FilePositionInformation",
"FileFullEaInformation",
"FileModeInformation",
"FileAlignmentInformation",
"FileAllInformation",
"FileAllocationInformation",
"FileEndOfFileInformation",
"FileAlternateNameInformation",
"FileStreamInformation",
"FilePipeInformation",
"FilePipeLocalInformation",
"FilePipeRemoteInformation",
"FileMailslotQueryInformation",
"FileMailslotSetInformation",
"FileCompressionInformation",
"FileCopyOnWriteInformation",
"FileCompletionInformation",
"FileMoveClusterInformation",
"FileOleClassIdInformation",
"FileOleStateBitsInformation",
"FileNetworkOpenInformation",
"FileObjectIdInformation",
"FileOleAllInformation",
"FileOleDirectoryInformation",
"FileContentIndexInformation",
"FileInheritContentIndexInformation",
"FileOleInformation",
"FileMaximumInformation",
};
//
// These are textual representations of the IRP_MJ_SET/GET_VOLUME_INFORMATION
// classes
//
CHAR *VolumeInformation[] = {
"",
"FileFsVolumeInformation",
"FileFsLabelInformation",
"FileFsSizeInformation",
"FileFsDeviceInformation",
"FileFsAttributeInformation",
"FileFsQuotaQueryInformation",
"FileFsQuotaSetInformation",
"FileFsControlQueryInformation",
"FileFsControlSetInformation",
"FileFsMaximumInformation",
};
//
// This Filemon's Fast I/O dispatch table. Note that NT assumes that
// file system drivers support some Fast I/O calls, so this table must
// be present for an file system filter driver
//
FAST_IO_DISPATCH FastIOHook = {
sizeof(FAST_IO_DISPATCH),
FilemonFastIoCheckifPossible,
FilemonFastIoRead,
FilemonFastIoWrite,
FilemonFastIoQueryBasicInfo,
FilemonFastIoQueryStandardInfo,
FilemonFastIoLock,
FilemonFastIoUnlockSingle,
FilemonFastIoUnlockAll,
FilemonFastIoUnlockAllByKey,
FilemonFastIoDeviceControl,
FilemonFastIoAcquireFile,
FilemonFastIoReleaseFile,
FilemonFastIoDetachDevice,
//
// new for NT 4.0
//
FilemonFastIoQueryNetworkOpenInfo,
FilemonFastIoAcquireForModWrite,
FilemonFastIoMdlRead,
FilemonFastIoMdlReadComplete,
FilemonFastIoPrepareMdlWrite,
FilemonFastIoMdlWriteComplete,
FilemonFastIoReadCompressed,
FilemonFastIoWriteCompressed,
FilemonFastIoMdlReadCompleteCompressed,
FilemonFastIoMdlWriteCompleteCompressed,
FilemonFastIoQueryOpen,
FilemonFastIoReleaseForModWrite,
FilemonFastIoAcquireForCcFlush,
FilemonFastIoReleaseForCcFlush
};
//----------------------------------------------------------------------
// 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -