📄 filemon.c
字号:
ULONG
FilemonGetProcessNameOffset(
VOID
)
{
PEPROCESS curproc;
int i;
curproc = PsGetCurrentProcess();
//
// Scan for 12KB, hoping the KPEB never grows that big!
//
for( i = 0; i < 3*PAGE_SIZE; i++ ) {
if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {
return i;
}
}
//
// Name not found - oh, well
//
return 0;
}
//----------------------------------------------------------------------
//
// FilemonGetProcess
//
// Uses undocumented data structure offsets to obtain the name of the
// currently executing process.
//
//----------------------------------------------------------------------
PCHAR
FilemonGetProcess(
PCHAR ProcessName
)
{
PEPROCESS curproc;
char *nameptr;
ULONG i;
//
// We only do this if we determined the process name offset
//
if( ProcessNameOffset ) {
//
// Get a pointer to the current process block
//
curproc = PsGetCurrentProcess();
//
// Dig into it to extract the name. Make sure to leave enough room
// in the buffer for the appended process ID.
//
nameptr = (PCHAR) curproc + ProcessNameOffset;
strncpy( ProcessName, nameptr, NT_PROCNAMELEN-1 );
ProcessName[NT_PROCNAMELEN-1] = 0;
#if defined(_IA64_)
sprintf( ProcessName + strlen(ProcessName), ":%I64d", PsGetCurrentProcessId());
#else
sprintf( ProcessName + strlen(ProcessName), ":%d", PsGetCurrentProcessId());
#endif
} else {
strcpy( ProcessName, "???" );
}
return ProcessName;
}
//----------------------------------------------------------------------
// H O O K / U N H O O K R O U T I N E S
//----------------------------------------------------------------------
#if DBG
//----------------------------------------------------------------------
//
// UnloadDetach
//
// Detaches from all devices for an unload
//
//----------------------------------------------------------------------
VOID
UnloadDetach(
VOID
)
{
ULONG drive, i;
PDEVICE_OBJECT device;
PHOOK_EXTENSION hookExt;
//
// Detach from file system devices
//
for( drive = 0; drive < 26; drive++ ) {
if( DriveHookDevices[drive] ) {
device = DriveHookDevices[drive];
hookExt = device->DeviceExtension;
IoDetachDevice( hookExt->FileSystem );
IoDeleteDevice( device );
for( i =0; i < 26; i++ ) {
if( DriveHookDevices[i] == device ) {
DriveHookDevices[i] = NULL;
}
}
}
}
//
// Detach from special devices
//
if( NamedPipeHookDevice ) {
IoDetachDevice( NamedPipeHookDevice );
IoDeleteDevice( NamedPipeHookDevice );
}
if( MailSlotHookDevice ) {
IoDetachDevice( MailSlotHookDevice );
IoDeleteDevice( MailSlotHookDevice );
}
}
#endif // DBG
//----------------------------------------------------------------------
//
// HookSpecialFs
//
// Hook the named pipe or mail slot file system.
//
//----------------------------------------------------------------------
BOOLEAN
HookSpecialFs(
IN PDRIVER_OBJECT DriverObject,
FILE_SYSTEM_TYPE FsType
)
{
IO_STATUS_BLOCK ioStatus;
HANDLE ntFileHandle;
OBJECT_ATTRIBUTES objectAttributes;
PDEVICE_OBJECT fileSysDevice;
PDEVICE_OBJECT topAttachDevice;
PDEVICE_OBJECT hookDevice;
UNICODE_STRING fileNameUnicodeString;
WCHAR npfsFilename[] = L"\\Device\\NamedPipe";
WCHAR msfsFilename[] = L"\\Device\\MailSlot";
NTSTATUS ntStatus;
ULONG i;
PFILE_OBJECT fileObject;
PHOOK_EXTENSION hookExtension;
//
// If we've already hooked it, just return success
//
if( FsType == NPFS && NamedPipeHookDevice ) return TRUE;
if( FsType == MSFS && MailSlotHookDevice ) return TRUE;
//
// We have to figure out what device to hook - first open the volume's
// root directory
//
if( FsType == NPFS ) RtlInitUnicodeString( &fileNameUnicodeString, npfsFilename );
else RtlInitUnicodeString( &fileNameUnicodeString, msfsFilename );
InitializeObjectAttributes( &objectAttributes, &fileNameUnicodeString,
OBJ_CASE_INSENSITIVE, NULL, NULL );
ntStatus = ZwCreateFile( &ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS,
&objectAttributes, &ioStatus, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE,
NULL, 0 );
if( !NT_SUCCESS( ntStatus ) ) {
DbgPrint(("Filemon: Could not open %s\n", FsType == NPFS ? "NPFS" : "MSFS", ntStatus ));
return FALSE;
}
DbgPrint(("Filemon: opened the root directory!!! handle: %x\n", ntFileHandle));
//
// Got the file handle, so now look-up the file-object it refers to
//
ntStatus = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA,
NULL, KernelMode, &fileObject, NULL );
if( !NT_SUCCESS( ntStatus )) {
DbgPrint(("Filemon: Could not get fileobject from %s handle: %x\n",
FsType == NPFS ? "NPFS" : "MSFS", ntStatus ));
ZwClose( ntFileHandle );
return FALSE;
}
//
// Next, find out what device is associated with the file object by getting its related
// device object
//
fileSysDevice = IoGetRelatedDeviceObject( fileObject );
if( ! fileSysDevice ) {
DbgPrint(("Filemon: Could not get related device object for %s: %x\n",
FsType == NPFS ? "NPFS" : "MSFS", ntStatus ));
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
return FALSE;
}
//
// The file system's device hasn't been hooked already, so make a hooking device
// object that will be attached to it.
//
ntStatus = IoCreateDevice( DriverObject,
sizeof(HOOK_EXTENSION),
NULL,
fileSysDevice->DeviceType,
0,
FALSE,
&hookDevice );
if( !NT_SUCCESS(ntStatus) ) {
DbgPrint(("Filemon: failed to create associated device %s: %x\n",
FsType == NPFS ? "NPFS" : "MSFS", ntStatus ));
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
return FALSE;
}
//
// Clear the device's init flag as per NT DDK KB article on creating device
// objects from a dispatch routine
//
hookDevice->Flags &= ~DO_DEVICE_INITIALIZING;
//
// Finally, attach to the device. The second we're successfully attached, we may
// start receiving IRPs targetted at the device we've hooked.
//
topAttachDevice = IoAttachDeviceToDeviceStack( hookDevice, fileSysDevice );
if( !topAttachDevice ) {
//
// Couldn' attach for some reason
//
DbgPrint(("Filemon: Connect with Filesystem failed: %s (%x) =>%x\n",
FsType == NPFS ? "NPFS" : "MSFS", fileSysDevice, ntStatus ));
//
// Derefence the object and get out
//
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
return FALSE;
} else {
DbgPrint(("Filemon: Successfully connected to Filesystem device %s\n",
FsType == NPFS ? "NPFS" : "MSFS" ));
}
//
// Setup the device extensions. The drive letter and file system object are stored
// in the extension.
//
hookExtension = hookDevice->DeviceExtension;
hookExtension->LogicalDrive = '\\';
hookExtension->FileSystem = topAttachDevice;
hookExtension->Hooked = TRUE;
hookExtension->Type = FsType;
//
// Close the file and update the hooked drive list by entering a
// pointer to the hook device object in it.
//
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
if( FsType == NPFS ) NamedPipeHookDevice = hookDevice;
else MailSlotHookDevice = hookDevice;
return TRUE;
}
//----------------------------------------------------------------------
//
// UnhookSpecialFs
//
// Unhook the named pipe file or mail slot system.
//
//----------------------------------------------------------------------
VOID
UnhookSpecialFs(
FILE_SYSTEM_TYPE FsType
)
{
PHOOK_EXTENSION hookExt;
if( FsType == NPFS && NamedPipeHookDevice ) {
hookExt = NamedPipeHookDevice->DeviceExtension;
hookExt->Hooked = FALSE;
NamedPipeHookDevice = NULL;
} else if( FsType == MSFS && MailSlotHookDevice ) {
hookExt = MailSlotHookDevice->DeviceExtension;
hookExt->Hooked = FALSE;
MailSlotHookDevice = NULL;
}
}
//----------------------------------------------------------------------
//
// HookDrive
//
// Hook the drive specified by determining which device object to
// attach to. The algorithm used here is similar to the one used
// internally by NT to determine which device object a file system request
// is directed at.
//
//----------------------------------------------------------------------
BOOLEAN
HookDrive(
IN ULONG Drive,
IN PDRIVER_OBJECT DriverObject
)
{
IO_STATUS_BLOCK ioStatus;
HANDLE ntFileHandle;
OBJECT_ATTRIBUTES objectAttributes;
PDEVICE_OBJECT fileSysDevice;
PDEVICE_OBJECT hookDevice;
UNICODE_STRING fileNameUnicodeString;
PFILE_FS_ATTRIBUTE_INFORMATION fileFsAttributes;
ULONG fileFsAttributesSize;
WCHAR filename[] = L"\\DosDevices\\A:\\";
NTSTATUS ntStatus;
ULONG i;
PFILE_OBJECT fileObject;
PHOOK_EXTENSION hookExtension;
//
// Is it a legal drive letter?
//
if( Drive >= 26 ) {
return FALSE;
}
//
// Has this drive already been hooked?
//
if( DriveHookDevices[Drive] == NULL ) {
//
// Frob the name to make it refer to the drive specified in the input
// parameter.
//
filename[12] = (CHAR) ('A'+Drive);
//
// We have to figure out what device to hook - first open the volume's
// root directory
//
RtlInitUnicodeString( &fileNameUnicodeString, filename );
InitializeObjectAttributes( &objectAttributes, &fileNameUnicodeString,
OBJ_CASE_INSENSITIVE, NULL, NULL );
ntStatus = ZwCreateFile( &ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS,
&objectAttributes, &ioStatus, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE,
NULL, 0 );
if( !NT_SUCCESS( ntStatus ) ) {
DbgPrint(("Filemon: Could not open drive %c: %x\n", 'A'+Drive, ntStatus ));
return FALSE;
}
DbgPrint(("Filemon: opened the root directory!!! handle: %x\n", ntFileHandle));
//
// Got the file handle, so now look-up the file-object it refers to
//
ntStatus = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA,
NULL, KernelMode, &fileObject, NULL );
if( !NT_SUCCESS( ntStatus )) {
DbgPrint(("Filemon: Could not get fileobject from handle: %c\n", 'A'+Drive ));
ZwClose( ntFileHandle );
return FALSE;
}
//
// Next, find out what device is associated with the file object by getting its related
// device object
//
fileSysDevice = IoGetRelatedDeviceObject( fileObject );
if( ! fileSysDevice ) {
DbgPrint(("Filemon: Could not get related device object: %c\n", 'A'+Drive ));
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
return FALSE;
}
//
// Check the device list to see if we've already attached to this particular device.
// This can happen when more than one drive letter is being handled by the same network
// redirecter
//
for( i = 0; i < 26; i++ ) {
if( DriveHookDevices[i] == fileSysDevice ) {
//
// If we're already watching it, associate this drive letter
// with the others that are handled by the same network driver. This
// enables us to intelligently update the hooking menus when the user
// specifies that one of the group should not be watched -we mark all
// of the related drives as unwatched as well
//
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
DriveHookDevices[ Drive ] = fileSysDevice;
return TRUE;
}
}
//
// The file system's device hasn't been hooked already, so make a hooking device
// object that will be attached to it.
//
ntStatus = IoCreateDevice( DriverObject,
sizeof(HOOK_EXTENSION),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -