首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

两种不应用过滤驱动从驱动获取数据的方法

2012-10-27 
两种不使用过滤驱动从驱动获取数据的方法一直想写点技术文章的,但是每次想起这事的时候没时间,有时间的时

两种不使用过滤驱动从驱动获取数据的方法
一直想写点技术文章的,但是每次想起这事的时候没时间,有时间的时候又提不起兴致J。

我们有时候需要从系统中某些驱动处理数据的方式,例如作一些过滤、对数据进行一些修改或者监视通过某个设备栈的数据等等。通常情况下是采用Filter Driver的方式实现。但是这样有种种局限性:容易暴露自己的存在、有些情况下可能不能再Detach掉,升级驱动的时候必须重启机器等等。

这里介绍两种通过HOOK方式截取数据的方法。

1、 Hook Dispatch例程。

首先通过ObReferenceObjectByName等函数拿到被Hook设备的DriverObject。有了这个之后,我们就可以用指向自己例程的指针改写MajorFunction数组里面的指针。



NTSTATUS ntStatus = STATUS_SUCCESS;

UNICODE_STRING wszDriverName;

PDRIVER_OBJECT pDriverObject = NULL;

PDRIVER_DISPATCH pOrgDispatch = NULL;

RtlInitUnicodeString( &wszDriverName, DRIVER_NAME);



ntStatus = ObReferenceObjectByName( &wszDriverName,

                  0,

                  NULL,

                  0,

                  *IoDriverObjectType,

                  //NULL,

                  KernelMode,

                  NULL,

                  (PVOID*)&pDriverObject);

if( !NT_SUCCESS(ntStatus))

{

                  DbgPrint( “ObReferenceObjectByName Fail.\r\n”);

                  return FALSE;

}

          pOrgDispatch = (PDRIVER_DISPATCH) InterlockedExchange( ( PLONG)&pDriverObject->MajorFunction[IRP_MJ_READ], (LONG)&DispatchMyRead);

          ……

卸载的时候同样这样修改回去即可。

这种方法比较方便,由于只需要改写一个函数指针,避免了inline hook的很多不稳定因素。另外,在调用原来的Dispatch例程的时候也只需要直接call它就行了。

但是,如果有些IRP不能立即完成的,例如键盘鼠标驱动的IRP,用这种方法就拿不到完成时候的数据了。因此我们还需要第二种方式J



2、 Hook Completion Routine。

在Hook掉的Dispatch里面,我们已经拿到了发到下层驱动的IRP。想在完成时再获得控制权,很简单,只需要再Hook掉Completion Routine。

NTSTATUS DispatchMyRead ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp)

{

         PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp);



         //需要保存一下旧的完成例程信息

              g_RecentIrpInfo.ComplettionRoutine = irpSp->CompletionRoutine;

              g_RecentIrpInfo.Context = irpSp->Context;

              g_RecentIrpInfo.Control = irpSp->Control;

              g_RecentIrpInfo.irpSp = irpSp;



              //安装自己的完成例程

              irpSp->CompletionRoutine = MyIoCompletion;

              irpSp->Context = NULL;

              irpSp->Control = SL_INVOKE_ON_SUCCESS;   



(来自:码农源库,http://www.vcclass.net/wordpress/?p=339)

热点排行