本文主要是介绍IRP Hook,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
谈到irp拦截,基本上有三种方式
- 在起点拦截
- 在半路拦截
- 在终点拦截
下面我们会详细分析这几种方式哪些是有效的,哪种是无效的。 要理解这几种拦截,我们需要看看irp地传送过程。
(注意并不是每种IRP都经过这些步骤,由于设备类型和IRP种类的不同某些步骤会改变或根本不存在。)
一、IRP创建。
由于IRP开始于某个实体调用I/O管理器函数创建它,可以使用下面任何一种函数创建IRP:
- IoBuildAsynchronousFsdRequest 创建异步IRP(不需要等待其完成)。该函数和下一个函数仅适用于创建某些类型的IRP。
- IoBuildSynchronousFsdRequest 创建同步IRP(需要等待其完成)
- IoBuildDeviceIoControlRequest 创建一个同步IRP_MJ_DEVICE_CONTROL或IRP_MJ_INTERNAL_DEVICE_CONTROL请求。
- IoAllocateIrp 创建上面三个函数不支持的其它种类的IRP。
由此我们知道,第一种起点拦截的办法就清楚了,那就是HOOK这几个IRP的创建函数
。 由于函数有多个,并且此时irp虽然已经创建,但是还没有进程初始化,也就是说irp堆栈单元的内容还没有填充。因此起点拦截的办法是得不到有用信息的。这种办法无效。
二、发往派遣例程
那么irp是什么时间初始化的呢?
创建完IRP后,你可以调用IoGetNextIrpStackLocation函数获得该IRP第一个堆栈单元的指针。然后初始化这个堆栈单元。
在初始化过程的最后,你需要填充MajorFunction代码。堆栈单元初始化完成后,就可以调用IoCallDriver函数把IRP发送到设备驱动程序了。
IoCallDriver是一个宏,它内部实现中调用了IofCallDriver. 因此,到这里便有了第二种拦截方法,即中途拦截。
三、派遣例程的作用
在派遣例程中完成irp。通常我们做的过滤驱动或者一些简单的驱动,都是这么完成的,直接在派遣例程中返回。不需要经过后面的步骤,派遣函数立即完成该IRP:
NTSTATUS OnStubDispatch( IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{Irp->IoStatus.Status = STATUS_SUCCESS;IoCompleteRequest (Irp, IO_NO_INCREMENT );return Irp->IoStatus.Status;
}
派遣例程把该IRP传递到处于同一堆栈的下层驱动程序 。 如果没处理,继续向下传, 如果中间FDO没有处理,最后传到最低层的硬件驱动上去,也就是我们所谓的PDO. 这个时候,I/O管理器就调用一次StartIo例程,硬件抽象层会通过硬件中断ISR,一个ISR最可能做的事就是调度DPC例程(推迟过程调用)。最后完成这个IRP , 并回到 I/O 管理器。
我们写驱动的时候,对感兴趣的irp,我们都会写派遣例程来进行处理。如果我们把派遣例程给替换了,便有了第三种的irp拦截。
-
一种是写一个过滤驱动放在要拦截的驱动的上层,这是一种安全的办法。例如:
如果我们想拦截系统的文件操作,就必须拦截I/O管理器发向文件系统驱动程序的IRP。而拦 截IRP最简单的方法莫过于创建一个上层过滤器设备对象并将之加入文件系统设备所在的设备堆栈中。具体方法如下:首先通过IoCreateDevice创 建自己的设备对象,然后调用IoGetDeviceObjectPointer来得到文件系统设备(Ntfs,Fastfat,Rdr或Mrxsmb, Cdfs)对象的指针,最后通过IoAttachDeviceToDeviceStack或者IoAttachDevice等函数,将自己的设备放到设备堆栈上成为一个过滤器。这是拦截IRP最常用也是最保险的方法。 -
还有一种就是直接替换要拦截驱动对象的派遣例程函数表。它的方法更简单且更为直接。
例如:如果我们想拦截系统的文件操作,它先通过ObReferenceObjectByName得到文件系统驱动对象的指针。然后将驱动对象中 MajorFunction数组中的打开,关闭,清除,设置文件信息,和写入调度例程入口地址改为我们驱动中相应钩子函数的入口地址来达到拦截IRP的目的。
总结:
1) 可用办法之一:hook IofCallDriver实现irp 拦截。
2) 可用办法之二:写一个过滤驱动,挂在你要hook其irp的那个驱动之上。
3) 可用办法之三:直接修改你要hook其irp的那个驱动的MajorFunction函数表。
例子参考:https://bbs.pediy.com/thread-60022.htm
这篇关于IRP Hook的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!