驱动是位于内核空间的一个模块;驱动程序是一个很范的概念,包括针对硬件的设备驱动,面向软件的内核驱动,文件系统驱动,以及其他的过滤驱动。 windows为了管理进程,线程,驱动等,本质上为其生成了一个对应的内核对象,并且定义了该对象上的若干方法。一个驱动,对应_DriverObject对象,驱动入口为DriverEntry(),只能被系统加载一次。加载以后驱动就像DLL一样位于系统内核空间。 驱动加载的时候,初始化DriverObject的派遣例程入口,即MajorFunction[],本质来说是一个函数指针数组,所以其内容可以随意改变,当然也可以被覆盖。典型的用法是,写一个passThrough例程,对MajorFunction数组的所有入口地址初始化;然后再对需要特殊处理的若干例程单独处理,如 MajorFunction[IRP_MJ_READ] = ReadFunc;理解了这些本质,也就知道一种内核HOOK的方法,即对目标驱动的派遣例程修改其入口地址,思想很简单。 一个DriverObject对应若干个DeviceObject,IO管理器只能将IRP发送到某个DriverObject的某个DeviceObject上,所以,真正的IRP的接收体是DeviceObject。相当于APP里的一个进程对应若干个窗口,消息只能发送到某个进程的某个窗口,没有窗口就不能接收消息;驱动也一样,没有DeviceObject,就不能收到IRP。 这里的DeviceObject,可以是代表一个具体的硬件设备,也可以是虚拟的设备,建立这样一个虚拟设备最本质的需求就是可以接收IRP数据包,便于通信,通常,也把这类主要用于通信的虚拟DeviceObject称为CDC。 驱动是分层的;一个驱动(DriverObject)对应一个或若干DeviceObject,那么在这些DeviceObject上,可以附加其他驱动的DeviceObject,形成设备栈。这样,发往设备栈的低层DeviceObject的IRP,会首先被设备栈顶层的DeviceObject捕获,顶层的处理完以后再往下层设备发,这样就形成了一层过滤。一切驱动级的文件保护,磁盘还原,杀毒引擎都是基于这个原理。 开发驱动,一定要深入理解操作系统和内核,必要的调试逆向技术。随着经验的积累,慢慢就成了高手。 |