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

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;

//OK,call下去。

ntStatus = g_ pOrgDispatch ( pDeviceObject, Irp);

return ntStatus;

}

在MyIoCompletion当然就是同样的标准hook操作咯,处理数据,call原来的IoCompletion。需要注意的是很多Irp并没有安装完成例程。

你可能感兴趣的:(数据,职场,获取,驱动,休闲)