看了文件过滤驱动的例子,照着写了几下。我想法是绑定完卷设备后,把所有的IRP都原封不动向下发,只是在passthru中打印个信息,表示经过了我的驱动,就是想看下效果。
用Device Tree查看,已成功绑定了D盘这个分区。用Dbgview查看,也能查看到输出信息。但是,绑定的D盘中,除了能用记事本打开的文件外,其他的文件比如exe或bmp,一打开或运行,就BSOD,显示:
STOP:0x0000008E(0xC0000005, 0x8057D74B,0xF54C7C30,0x00000000)
到底咋回事尼?
因为哪块需要注意的细节没处理好? 或是哪块必须处理的没处理?请教各位兄台!
#include "ntddk.h"
//----------------------------------------------------------------------
// G L O B A L S
//----------------------------------------------------------------------
#define MAX_DEVNAME_LENGTH 64
PDEVICE_OBJECT myfilterobj = NULL;
PDEVICE_OBJECT fileSysDevice = NULL;
PDRIVER_OBJECT mydriverobject = NULL;
//----------------------------------------------------------------------
// 数 据 结 构
//----------------------------------------------------------------------
typedef struct tagDEVICE_EXTENSION {
// 我们所绑定的文件系统设备
PDEVICE_OBJECT AttachedToDeviceObject;
// 与我们的文件系统设备相关的真实设备(磁盘),这个用于绑定时使用。
PDEVICE_OBJECT StorageStackDeviceObject;
// 如果我们绑定了一个卷,这是物理磁盘卷名。否则这是我们绑定的控制设备名。
UNICODE_STRING DeviceName;
// 用来保存名字字符串的缓冲区
WCHAR DeviceNameBuffer[MAX_DEVNAME_LENGTH];
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
//----------------------------------------------------------------------
// 函 数
//----------------------------------------------------------------------
NTSTATUS MyPassThr(PDEVICE_OBJECT device,PIRP irp) ;
NTSTATUS
MyAttachHardDisk(PDRIVER_OBJECT driver) ;
void MyUnload(IN PDRIVER_OBJECT driver);
NTSTATUS
MyCreate(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
//----------------------------------------------------------------------
//----------------------------------------------------------------------
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
ULONG i;
// 所有的分发函数都设置成一样的
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
driver->MajorFunction[i] = MyPassThr;
}
// DbgPrint("This is my filter test!\n");
mydriverobject = driver;
// 支持动态卸载
driver->DriverUnload = MyUnload;
// 绑定卷设备
MyAttachHardDisk(driver);
return STATUS_SUCCESS;
}
NTSTATUS
MyAttachHardDisk(
PDRIVER_OBJECT driver)
{
NTSTATUS status;
PUNICODE_STRING DeviceName;
PDEVICE_OBJECT topdev;
HANDLE ntFileHandle = NULL;
UNICODE_STRING nameString = RTL_CONSTANT_STRING(L"\\DosDevices\\D:\\");
OBJECT_ATTRIBUTES objectAttributes;
PFILE_OBJECT fileObject;
PDEVICE_EXTENSION devExt = NULL;
IO_STATUS_BLOCK ioStatus;
//-------------------------------
InitializeObjectAttributes( &objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
NULL, NULL );
status = 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( status ) )
{
DbgPrint(("Filemon: Could not open drive : \n"));
return FALSE;
}
DbgPrint("status of ZwCreateFile: %ws %d\n",status,status);
//
// Got the file handle, so now look-up the file-object it refers to
//
status = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA, NULL,
KernelMode, &fileObject, NULL );
if( !NT_SUCCESS( status )) {
DbgPrint(("Filemon: Could not get fileobject from handle\n"));
ZwClose( ntFileHandle );
return FALSE;
}
DbgPrint("status of ObReferenceObjectByHandle: %ws %d\n",status,status);
//
// 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\n" ));
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
return FALSE;
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// 生成设备,然后绑定之。
status = IoCreateDevice(driver,
sizeof(DEVICE_EXTENSION),
NULL, //设备名称为空
fileSysDevice->DeviceType,
0,
FALSE,
&myfilterobj);
if(!NT_SUCCESS(status))
{
DbgPrint("Binding Device failed!");
return status;
}
DbgPrint("status of IoCreateDevie: %d %ws\n",status,status);
//设置标志位:
if(fileSysDevice->Flags & DO_BUFFERED_IO) //
myfilterobj->Flags |= DO_BUFFERED_IO;
if(fileSysDevice->Flags & DO_DIRECT_IO) //
myfilterobj->Flags |= DO_DIRECT_IO;
if(fileSysDevice->Characteristics & FILE_DEVICE_SECURE_OPEN) //
myfilterobj->Characteristics |= FILE_DEVICE_SECURE_OPEN;
//设备绑定
topdev = IoAttachDeviceToDeviceStack(myfilterobj, fileSysDevice);
if (topdev == NULL)
{
// 如果绑定失败了,销毁设备,返回错误。
IoDeleteDevice(myfilterobj);
myfilterobj = NULL;
status = STATUS_UNSUCCESSFUL;
return status;
}
///////////////设置生成设备的设备扩展, devExt为中转变量//////////////////////////////////
devExt = myfilterobj->DeviceExtension;
devExt->AttachedToDeviceObject = fileSysDevice;
/////////////////////////////////////////////////////////////
// 设置这个设备已经启动
myfilterobj->Flags &= ~DO_DEVICE_INITIALIZING;
// 最后:
// Close the file and update the hooked drive list by entering a
// pointer to the hook device object in it.
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
return STATUS_SUCCESS;
}
NTSTATUS MyPassThr(PDEVICE_OBJECT device,PIRP irp)
{
PDEVICE_EXTENSION pFilterExt = device->DeviceExtension;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(irp);
//看下效果
DbgPrint("Starting MyPassThr: %d\n", IrpSp->MajorFunction);
IoSkipCurrentIrpStackLocation( irp );
return IoCallDriver(pFilterExt->AttachedToDeviceObject, irp );
}
void MyUnload(IN PDRIVER_OBJECT driver)
{
//解除挂接,使用IoDetachDevice
IoDetachDevice(fileSysDevice);
//删除设备
IoDeleteDevice(myfilterobj);
myfilterobj = NULL;
fileSysDevice = NULL;
DbgPrint("MyFilter.SYS: Unstall the driver...\n");
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)