阅读:3855回复:25
关于过滤驱动程序
因应用需要,我要为一个硬件厂商提供的驱动程序写一个过滤驱动程序,以便能够在系统核心层对其控制。但我从未写过类似程序,不知能否对任何驱动程序写过滤驱动,来截取发送给它的IRP?我用IoGetDevicePointer,想获得另一个驱动程序的设备对象的指针,但结果不对。获得的DeviceObject的属性与目标DeviceObject完全不符。哪位大侠开发过过滤驱动程序,请指点一二
|
|
|
沙发#
发布于:2002-04-02 10:47
我的程序如下:
RtlInitUnicodeString(&uniDeviceName, L\"\\\\Device\\\\myDevice\"); status=IoGetDeviceObjectPointer(&uniDeviceName, FILE_ALL_ACCESS, &TargetFile, &TargetDevice ); 但通过SOFTICE察看,获得的TargetDevice中的DriverObject->DrierName为FileSystem\\RAW 我用WinObj察看我的设备对象myDevice, 的确存在。为什么函数返回的DeviceObject不对呢? |
|
|
板凳#
发布于:2002-04-02 11:00
你先做下去
别忙着在代码这么少的情况下就用softice看 况且怎么是看DriverObject->DriverName呢?不懂 |
|
|
地板#
发布于:2002-04-02 11:12
那是因为和你的驱动程序在同一个层次的另外一个驱动程序在你的驱动程序的上面,
例如有设备对象A、B、C、D D、C和B是A的过滤设备对象,他们都是钩挂在A之上, 先讨论B、C的层次关系,他们是 A->B->C还是A->C->B这个就要由B和C之间的加载顺序确定 当A、B、C都加载了最后加载D那么D通过你使用的那些函数就会得到第三个过滤设备对象 |
|
地下室#
发布于:2002-04-02 13:15
1. 好象还没有到连接到设备栈这一步
2. IoGetDeviceObjectPointer与设备栈有关吗? |
|
|
5楼#
发布于:2002-04-02 13:40
我的程序如下: 你的ACCESS_MASK参数设置可能有问题,FILE_ALL_ACCESS参数一般很少使用,你可以改用FILE_READ_DATA试试。 |
|
|
6楼#
发布于:2002-04-03 08:56
Re:Tom_lyd
我改了MaskMode,但没有作用 Re:Iamme ----------------------------------------- 1. 好象还没有到连接到设备栈这一步 2. IoGetDeviceObjectPointer与设备栈有关吗? ------------------------------------------ 我的理解是IoGetDeviceObjectPointer应该得到设备对象的指针,那么通过softice,应该看到我的目标设备。而IoAttachDeviceToDeviceStack只是把我新创建的设备对象连接到目标设备上。我的理解是否正确? Re:Guardee 你的意思是,在我的目标设备的上层可能有别的过滤设备?但我的目标设备是我自己写的另一个Driver,有可能吗? 我的问题: 1.能否对任何设备对象写过滤驱动程序来截取它的IRP包? 2.IoGetDeviceObjectPointer得到的是否就是目标设备对象? 3.得到目标设备对象后还有什么操作? 老板催得很急,哪位大虾做过过滤驱动的,能否email源码给我?我的email:ymvivian@sina.com.cn |
|
|
7楼#
发布于:2002-04-03 08:59
sorry, email: ymvivian@sian.com
|
|
|
8楼#
发布于:2002-04-03 09:46
1.能否对任何设备对象写过滤驱动程序来截取它的IRP包?
应该是这样的 2.IoGetDeviceObjectPointer得到的是否就是目标设备对象? 是的 3.得到目标设备对象后还有什么操作? 对于过滤驱动那肯定要用IoAttachDeviceToDeviceStack连接 到设备栈喽 然后就可以过滤到信息喽 另:跟maskmode应该没什么关系 你应该先做下去,先看看能不能达到你的目的再说 |
|
|
9楼#
发布于:2002-04-03 16:17
多谢各位倾囊相助,我终于“先做下去再说了”,已经能够截获发到另一个驱动程序的IRP。“万里长征刚走完了第一步”
接下来要做的是为一个厂商提供的硬件驱动程序写过滤驱动,我已经hook到它的设备上,但不知道如何控制它。我用它提供的应用程序编程接口来调用它,本想发现接口关系。但出现了一个问题:如果先启动过滤驱动程序,它的open函数返回失败。但如果先调用open,成功,但过滤驱动程序的IoGetDeviceObjectPointer返回失败。这下我又被卡住了。 怎样才能既启动过滤驱动程序,又能用App编程函数调用它呢?这回跟MaskMode有关吗?我用了File_Share_Read, 不行。 |
|
|
10楼#
发布于:2002-04-03 18:07
//如果先启动过滤驱动程序,它的open函数返回失败
一定是你的过滤驱动有问题 过滤驱动不应该影响到应用的 |
|
|
11楼#
发布于:2002-04-03 21:48
函数IoGetDeviceObjectPointer返回失败,有下面几种情况:
AccessMask为FILE_READ_DATA或FILE_READ_ACCESS a. 1>. 先启动目标设备驱动程序 2>. 启动过滤驱动程序 3>. 应用程序试图获得目标设备的句柄,返回失败 b. 1> 启动目标设备驱动程序 2> 应用程序获得目标设备的句柄 3> 启动过滤驱动程序,IoGetDeviceObjectPointer返回失败,STATUS_SHARING_VIOLATION 若将AccessMask设为FILE_ANY_ACCESS,IoGetDeviceObjectPointer返回STATUS_INVALID_DEVICE_REQUEST 应该将AccessMask设为什么呢? |
|
|
12楼#
发布于:2002-04-03 23:47
一般都是进行A的步骤,我觉得是你的过滤驱动程序有问题
|
|
13楼#
发布于:2002-04-04 08:34
函数IoGetDeviceObjectPointer返回失败,有下面几种情况: 采用File monitor中的方法试试看,如下 1.ZwCreateFile打开到目标驱动程序的连接,返回设备句柄。在此之前要初始化一个OBJCT_ATTRIBUTES 结构变量。 2.将句柄转化为设备对象指针。ObReferenceObjectByHandle 3.IoGetRelatedObjectDevice得到可能的顶层过滤设备。(这里是你自己的设备对象,设备栈深度应该为1,即传入参数和返回应该为同一值)。 4.创建你的过滤设备对象,并挂接到设备栈。IoCreateDevice(),IoAttachDeviceToDeviceStack(). 这样做,或许有用,至少可以试试。 Best regards ! |
|
|
14楼#
发布于:2002-04-04 08:36
这是Filemonitor中的挂接到目标驱动的源码,你可以参考一下。
相关源码: BOOLEAN HookDrive( IN ULONG Drive, IN PDRIVER_OBJECT DriverObject ) { IO_STATUS_BLOCK ioStatus; HANDLE ntFileHandle; OBJECT_ATTRIBUTES objectAttributes; PDEVICE_OBJECT fileSysDevice; //lower device object PDEVICE_OBJECT hookDevice; //our own device object UNICODE_STRING fileNameUnicodeString; PFILE_FS_ATTRIBUTE_INFORMATION fileFsAttributes; ULONG fileFsAttributesSize; WCHAR filename[] = L\"\\\\DosDevices\\\\A:\\\\\"; //??shoule be link name or internal name ? NTSTATUS ntStatus; ULONG i; PFILE_OBJECT fileObject; PDEVICE_EXTENSION hookExtension; fileFsAttributes; //---------------------------------------------------- // Is it a legal drive letter? //---------------------------------------------------- if( Drive >= 26 ) { return FALSE; } //---------------------------------------------------- // Has this drive already been hooked? //---------------------------------------------------- if( DriveHookDevices[Drive] == NULL ) //have not been hooked { //---------------------------------------------------- // 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, //output file handle SYNCHRONIZE|FILE_ANY_ACCESS, &objectAttributes, &ioStatus, //output status of result NULL, //pallocate size 0, //file attributes FILE_SHARE_READ|FILE_SHARE_WRITE, //share access FILE_OPEN, //create disposition FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, //create options NULL, //EA buffer 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 == 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; //share the same filteror 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(DEVICE_EXTENSION), NULL, fileSysDevice->DeviceType, 0, FALSE, //not exclusive &hookDevice ); if( !NT_SUCCESS(ntStatus) ) { DbgPrint((\"Filemon: failed to create associated device: %c\\n\", \'A\'+Drive )); ObDereferenceObject( fileObject ); ZwClose( ntFileHandle ); return FALSE; } //---------------------------------------------------------------------- // // Clear the initialize flag in device object\'s flag field // //---------------------------------------------------------------------- hookDevice->Flags &= ~DO_DEVICE_INITIALIZING; //---------------------------------------------------------------------- // Setup the device extensions. The drive letter and file system // object are stored in the extension. //---------------------------------------------------------------------- hookExtension = (PDEVICE_EXTENSION)hookDevice->DeviceExtension; hookExtension->LogicalDrive = \'A\'+Drive; hookExtension->FileSystem = fileSysDevice; hookExtension->Hooked = TRUE; hookExtension->Type = STANDARD; //---------------------------------------------------------------------- // // Attach my device object to the top level of target device object // //---------------------------------------------------------------------- ntStatus = IoAttachDeviceByPointer( hookDevice, fileSysDevice ); if( !NT_SUCCESS(ntStatus) ) { //---------------------------------------------------------------------- // Couldn\' attach for some reason //---------------------------------------------------------------------- DbgPrint((\"Filemon: Connect with Filesystem failed: %c (%x) =>%x\\n\", \'A\'+Drive, fileSysDevice, ntStatus )); //---------------------------------------------------------------------- // Derefence the object and get out //---------------------------------------------------------------------- ObDereferenceObject( fileObject ); ZwClose( ntFileHandle ); return FALSE; } else { //---------------------------------------------------------------------- // Make a new drive group for the device,l if it does not have one // already //---------------------------------------------------------------------- DbgPrint((\"Filemon: Successfully connected to Filesystem device %c\\n\", \'A\'+Drive )); } //---------------------------------------------------------------------- // Determine if this is a NTFS drive //---------------------------------------------------------------------- fileFsAttributesSize = sizeof( FILE_FS_ATTRIBUTE_INFORMATION) + MAXPATHLEN; hookExtension->FsAttributes = (PFILE_FS_ATTRIBUTE_INFORMATION) ExAllocatePool(NonPagedPool, fileFsAttributesSize ); //------------------------------------------------------ // IoQueryVolumeInformation is documented in ifs kit // it\'s prototype is declared in ntifs.h file //------------------------------------------------------ if( hookExtension->FsAttributes && !NT_SUCCESS( IoQueryVolumeInformation( fileObject, FileFsAttributeInformation, fileFsAttributesSize, hookExtension->FsAttributes, &fileFsAttributesSize ) )) { //--------------------------------------------------------------------------- // On failure, we just don\'t have attributes for this file system //--------------------------------------------------------------------------- ExFreePool( hookExtension->FsAttributes ); hookExtension->FsAttributes = NULL; } //--------------------------------------------------------------------------- // Close the file and update the hooked drive list by entering a // pointer to the hook device object in it. //--------------------------------------------------------------------------- ObDereferenceObject( fileObject ); ZwClose( ntFileHandle ); DriveHookDevices[Drive] = hookDevice; //new created filteror } else { //If I have been hooked it,only confirm the Hooked flag in extension hookExtension = DriveHookDevices[Drive]->DeviceExtension; hookExtension->Hooked = TRUE; } return TRUE; } |
|
|
15楼#
发布于:2002-04-04 14:15
多谢大家,只可惜分太少了,不好意思。:(
我检查到了过滤驱动程序的一个bug,现在过滤我自己的另一个驱动程序,走a步骤能够成功,即1>. 先启动目标设备驱动程序 2>. 启动过滤驱动程序 3>. 应用程序获得目标设备的句柄 但是我对于厂家提供的驱动程序,启动过滤驱动程序后,它的open函数仍返回失败。应用程序和驱动程序获得设备的句柄或指针,是否是同一原理?能否讲讲理论上的关系? Re: Tom_lyd File monitor采用的方法和IoGetDeviceObjectPointer有什么不一样吗?不过我会试一试的。 |
|
|
16楼#
发布于:2002-04-04 15:25
-----------------------------------------------------
采用File monitor中的方法试试看,如下 1.ZwCreateFile打开到目标驱动程序的连接,返回设备句柄。在此之前要初始化一个OBJCT_ATTRIBUTES 结构变量。 2.将句柄转化为设备对象指针。ObReferenceObjectByHandle 3.IoGetRelatedObjectDevice得到可能的顶层过滤设备。(这里是你自己的设备对象,设备栈深度应该为1,即传入参数和返回应该为同一值)。 4.创建你的过滤设备对象,并挂接到设备栈。IoCreateDevice(),IoAttachDeviceToDeviceStack(). 这样做,或许有用,至少可以试试。 ---------------------------------------------------- Re:Tom_lyd 我试过了,和IoGetDeviceObjectPointer效果相同,没有改进。若我先调用应用程序的open函数,过滤驱动程序的ZwCreateFile返回STATUS_ACCESS_DENIED,若先启动过滤驱动程序,open函数失败。 Now, what should I do? |
|
|
17楼#
发布于:2002-04-05 16:31
我看不懂了
你不是要写过滤驱动吗? 不是先获得了目标设备的指针,又连接好了 不是已经可以过滤到IRP了吗? 怎么还用ZwCreateFile打开设备做什么??? 另:你的这个厂商的设备是不是只能独占访问啊? |
|
|
18楼#
发布于:2002-04-07 01:49
多谢各位倾囊相助,我终于“先做下去再说了”,已经能够截获发到另一个驱动程序的IRP。“万里长征刚走完了第一步” 你怎么确信你的Filter已经Hook到该设备上? Filter必须支持下层驱动的所有IRP_MJ_Functions,open失败,应该是你的IRP_MJ_CREATE有问题,对于启动下层驱动的IRP_MJ_CREATE,必须递下去(如何区分启动下层驱动还是启动你自己,参考File Monitor)。 |
|
|
19楼#
发布于:2002-04-07 01:57
to yavv:
关于你前面的问题,没太明白你的意思,不过 一般在调用 IoGetDeviceObjectPointer 之后, 需要调用 ObReferenceObjectByPointer 以增加 其引用计数。 另: File Monitor 的做法是好的! |
|
|
上一页
下一页