📄 filemon.c
字号:
//======================================================================
//
// Filemon.c
//
// Sysinternals - www.sysinternals.com
// Copyright (C) 1996-2001 Mark Russinovich and Bryce Cogswell
//
// Passthrough file system filter device driver.
//
// Notes: The reason that we use NonPagedPool even though the driver
// only accesses allocated buffer at PASSIVE_LEVEL, is that touching
// a paged pool buffer can generate a page fault, and if the paging
// file is on a drive that filemon is monitoring filemon would be
// reentered to handle the page fault. We want to avoid that and so
// we only use nonpaged pool.
//
//======================================================================
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"
#include "..\exe\ioctlcmd.h"
#include "filemon.h"
//----------------------------------------------------------------------
// F O R W A R D D E C L A R A T I O N S
//----------------------------------------------------------------------
//
// 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
);
BOOLEAN
ApplyFilters(
PCHAR Text
);
//
// Unload routine (debug builds only)
//
VOID
FilemonUnload(
IN PDRIVER_OBJECT DriverObject
);
//----------------------------------------------------------------------
// G L O B A L S
//----------------------------------------------------------------------
//
// This is our Driver Object
//
PDRIVER_OBJECT FilemonDriver;
//
// 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
//
ERESOURCE FilterResource;
//
// Array of process and path filters
//
ULONG NumIncludeFilters = 0;
PCHAR IncludeFilters[MAXFILTERS];
ULONG NumExcludeFilters = 0;
PCHAR ExcludeFilters[MAXFILTERS];
//
// 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.
//
#if DBG
ULONG OutstandingIRPCount = 0;
#endif // DBG
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 DriveHookDevices[26];
//
// Current bitmask of hooked drives
//
ULONG CurrentDriveSet = 0;
//
// The special file system hook devices
//
PDEVICE_OBJECT NamedPipeHookDevice = NULL;
PDEVICE_OBJECT MailSlotHookDevice = NULL;
//
// 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];
//
// Reader/Writer lock to protect hash table.
//
ERESOURCE HashResource;
//
// The current output buffer
//
PLOG_BUF CurrentLog = 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
//
FAST_MUTEX LogMutex;
//
// 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 NumLog = 0;
ULONG MaxLog = (1024*1024)/LOGBUFSIZE;
//
// Full path name lookaside for dispatch entry
//
NPAGED_LOOKASIDE_LIST FullPathLookaside;
//
// We use this string for a path name when we're out of resources
//
CHAR InsufficientResources[] = "<INSUFFICIENT MEMORY>";
//
// 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",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -