📄 fspylib.c
字号:
IsAttached - This is set to TRUE if our filter is attached to this device
stack, otherwise this is set to FALSE.
StackDeviceObject - Set to a device object in the stack identified by the
DeviceName. If this is non-NULL, the caller is responsible for removing
the reference put on this object before it was returned.
AttachedDeviceObject - Set to the DeviceObject which FileSpy has previously
attached to the device stack identify by DeviceName. If this is
non-NULL, the caller is responsible for removing the reference put on
this object before it was returned.
Return Value:
Returns STATUS_SUCCESS if we were able to successfully translate the
DeviceName into a device stack and return the StackDeviceObject. If an
error occurs during the translation of the DeviceName into a device stack,
the appropriate error code is returned.
--*/
{
PNAME_CONTROL volumeName = NULL;
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK openStatus;
PFILE_OBJECT volumeFileObject;
HANDLE fileHandle;
PDEVICE_OBJECT baseFsDeviceObject;
PAGED_CODE();
//
// Initialize return state
//
ASSERT( NULL != StackDeviceObject );
ASSERT( NULL != OurAttachedDeviceObject );
ASSERT( NULL != IsAttached );
*StackDeviceObject = NULL;
*OurAttachedDeviceObject = NULL;
*IsAttached = FALSE;
//
// Setup the name to open
//
status = NLAllocateNameControl( &volumeName, &gFileSpyNameBufferLookasideList );
if (!NT_SUCCESS( status )) {
return status;
}
status = NLCheckAndGrowNameControl( volumeName,
sizeof(L"\\DosDevices\\") +
DeviceName->Name.Length );
if (!NT_SUCCESS( status )) {
return status;
}
RtlAppendUnicodeToString( &volumeName->Name, L"\\DosDevices\\" );
RtlAppendUnicodeStringToString( &volumeName->Name, &DeviceName->Name );
//
// Initialize objectAttributes. Note that this does not *copy* the
// volume name, so we cannot release volumeName until we're done with
// objectAttributes.
//
InitializeObjectAttributes( &objectAttributes,
&volumeName->Name,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL );
//
// Open the file object for the given device.
//
status = ZwCreateFile( &fileHandle,
SYNCHRONIZE|FILE_READ_DATA,
&objectAttributes,
&openStatus,
NULL,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
NLFreeNameControl( volumeName, &gFileSpyNameBufferLookasideList );
if (STATUS_OBJECT_PATH_NOT_FOUND == status ||
STATUS_OBJECT_NAME_INVALID == status) {
//
// Maybe this name didn't need the "\DosDevices\" prepended to the
// name. Try the open again using just the DeviceName passed in.
//
InitializeObjectAttributes( &objectAttributes,
&DeviceName->Name,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL );
//
// Open the file object for the given device.
//
status = ZwCreateFile( &fileHandle,
SYNCHRONIZE|FILE_READ_DATA,
&objectAttributes,
&openStatus,
NULL,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if (!NT_SUCCESS( status )) {
return status;
}
//
// We were able to open the device using the name passed in, so
// now we will fall through and do the rest of this work.
//
} else if (!NT_SUCCESS( status )) {
return status;
}
//
// Get a pointer to the volumes file object.
//
status = ObReferenceObjectByHandle( fileHandle,
FILE_READ_DATA,
*IoFileObjectType,
KernelMode,
&volumeFileObject,
NULL );
if(!NT_SUCCESS( status )) {
ZwClose( fileHandle );
return status;
}
//
// Get the device object we want to attach to (parent device object
// in chain).
//
baseFsDeviceObject = IoGetBaseFileSystemDeviceObject( volumeFileObject );
if (baseFsDeviceObject == NULL) {
ObDereferenceObject( volumeFileObject );
ZwClose( fileHandle );
return STATUS_INVALID_DEVICE_STATE;
}
//
// Now see if we are attached to this device stack. Note that we need to
// keep this file object open while we do this search to ensure that the
// stack won't get torn down while SpyIsAttachedToDevice does its work.
//
*IsAttached = SpyIsAttachedToDevice( baseFsDeviceObject,
OurAttachedDeviceObject );
//
// Return the base file system's device object to represent this device
// stack even if we didn't find our device object in the stack.
//
ObReferenceObject( baseFsDeviceObject );
*StackDeviceObject = baseFsDeviceObject;
//
// Close our handle
//
ObDereferenceObject( volumeFileObject );
ZwClose( fileHandle );
return STATUS_SUCCESS;
}
//
// VERSION NOTE:
//
// In Windows 2000, the APIs to safely walk an arbitrary file system device
// stack were not supported. If we can guarantee that a device stack won't
// be torn down during the walking of the device stack, we can walk from
// the base file system's device object up to the top of the device stack
// to see if we are attached. We know the device stack will not go away if
// we are in the process of processing a mount request OR we have a file object
// open on this device.
//
// In Windows XP and later, the IO Manager provides APIs that will allow us to
// walk through the chain safely using reference counts to protect the device
// object from going away while we are inspecting it. This can be done at any
// time.
//
// MULTIVERSION NOTE:
//
// If built for Windows XP or later, this driver is built to run on
// multiple versions. When this is the case, we will test for the presence of
// the new IO Manager routines that allow for a filter to safely walk the file
// system device stack and use those APIs if they are present to determine if
// we have already attached to this volume. If these new IO Manager routines
// are not present, we will assume that we are at the bottom of the file
// system stack and walk up the stack looking for our device object.
//
BOOLEAN
SpyIsAttachedToDevice (
IN PDEVICE_OBJECT DeviceObject,
IN OUT PDEVICE_OBJECT *AttachedDeviceObject OPTIONAL
)
{
PAGED_CODE();
#if WINVER >= 0x0501
if (IS_WINDOWSXP_OR_LATER()) {
ASSERT( NULL != gSpyDynamicFunctions.GetLowerDeviceObject &&
NULL != gSpyDynamicFunctions.GetDeviceAttachmentBaseRef );
return SpyIsAttachedToDeviceWXPAndLater( DeviceObject,
AttachedDeviceObject );
} else {
#endif
return SpyIsAttachedToDeviceW2K( DeviceObject, AttachedDeviceObject );
#if WINVER >= 0x0501
}
#endif
}
BOOLEAN
SpyIsAttachedToDeviceW2K (
PDEVICE_OBJECT DeviceObject,
PDEVICE_OBJECT *AttachedDeviceObject OPTIONAL
)
/*++
Routine Description:
VERSION: Windows 2000
This routine walks up the device stack from the DeviceObject passed in
looking for a device object that belongs to our filter.
Note: For this routine to operate safely, the caller must ensure two
things:
* the DeviceObject is the base file system's device object and therefore
is at the bottom of the file system stack
* this device stack won't be going away while we walk up this stack. If
we currently have a file object open for this device stack or we are
in the process of mounting this device, this guarantee is satisfied.
Arguments:
DeviceObject - The device chain we want to look through
AttachedDeviceObject - Set to the DeviceObject which FileSpy
has previously attached to DeviceObject. If this is non-NULL,
the caller must clear the reference put on this device object.
Return Value:
TRUE if we are attached, FALSE if not
--*/
{
PDEVICE_OBJECT currentDeviceObject;
PAGED_CODE();
for (currentDeviceObject = DeviceObject;
currentDeviceObject != NULL;
currentDeviceObject = currentDeviceObject->AttachedDevice) {
if (IS_FILESPY_DEVICE_OBJECT( currentDeviceObject )) {
//
// We are attached. If requested, return the found device object.
//
if (ARGUMENT_PRESENT( AttachedDeviceObject )) {
ObReferenceObject( currentDeviceObject );
*AttachedDeviceObject = currentDeviceObject;
}
return TRUE;
}
}
//
// We did not find ourselves on the attachment chain. Return a NULL
// device object pointer (if requested) and return we did not find
// ourselves.
//
if (ARGUMENT_PRESENT( AttachedDeviceObject )) {
*AttachedDeviceObject = NULL;
}
return FALSE;
}
#if WINVER >= 0x0501
BOOLEAN
SpyIsAttachedToDeviceWXPAndLater (
PDEVICE_OBJECT DeviceObject,
PDEVICE_OBJECT *AttachedDeviceObject OPTIONAL
)
/*++
Routine Description:
VERSION: Windows XP and later
This walks down the attachment chain looking for a device object that
belongs to this driver. If one is found, the attached device object
is returned in AttachedDeviceObject.
Arguments:
DeviceObject - The device chain we want to look through
AttachedDeviceObject - Set to the DeviceObject which FileSpy
has previously attached to DeviceObject.
Return Value:
TRUE if we are attached, FALSE if not
--*/
{
PDEVICE_OBJECT currentDevObj;
PDEVICE_OBJECT nextDevObj;
PAGED_CODE();
//
// Get the device object at the TOP of the attachment chain
//
ASSERT( NULL != gSpyDynamicFunctions.GetAttachedDeviceReference );
currentDevObj = (gSpyDynamicFunctions.GetAttachedDeviceReference)( DeviceObject );
//
// Scan down the list to find our device object.
//
do {
if (IS_FILESPY_DEVICE_OBJECT( currentDevObj )) {
//
// We have found that we are already attached. If we are
// returning the device object, leave it referenced else remove
// the reference.
//
if (NULL != AttachedDeviceObject) {
*AttachedDeviceObject = currentDevObj;
} else {
ObDereferenceObject( currentDevObj );
}
return TRUE;
}
//
// Get the next attached object. This puts a reference on
// the device object.
//
ASSERT( NULL != gSpyDynamicFunctions.GetLowerDeviceObject );
nextDevObj = (gSpyDynamicFunctions.GetLowerDeviceObject)( currentDevObj );
//
// Dereference our current device object, before
// moving to the next one.
//
ObDereferenceObject( currentDevObj );
currentDevObj = nextDevObj;
} while (NULL != currentDevObj);
//
// Mark no device returned.
//
if (ARGUMENT_PRESENT(AttachedDeviceObject)) {
*AttachedDeviceObject = NULL;
}
return FALSE;
}
#endif //WINVER >= 0x0501
NTSTATUS
SpyAttachToMountedDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT FilespyDeviceObject
)
/*++
Routine Description:
This routine will attach the FileSpyDeviceObject to the filter stack
that DeviceObject is in.
NOTE: If there is an error in attaching, the caller is responsible
for deleting the FileSpyDeviceObject.
Arguments:
DeviceObject - The device object in the stack to which we want to attach.
FilespyDeviceObject - The filespy device object that is to be attached to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -