过滤,filter,过滤是在不影响上层和下层接口的情况下,在Windows系统内核中加入新的层,从而不需要修改上层的软件或者下层的真实驱动程序,就加入了新的功能。
举个例子:
实时监控的反病毒程序。任何高层软件或者Windows的文件系统都没有考虑过应该什么时候去检查文件中是否含有某个病毒的特征 码,也不应该要求某个软件或者Windows的文件系统去考虑这些;反病毒程序需要在不改变文件系统的上层和下层接口的情况下,在中间加入一个过滤 层,这样就可以在上层软件读取文件、下层驱动提供数据时,对这些数据进行扫描,看其中是否含有某个病毒的特征码。这是一个很典型的过滤过程。
进行过滤的最主要的方法是对一个设备对象(Device Object)进行绑定。
Windows系统之所以可以运作,是因为Windows中已经存在许多提供了各种功能的设备对象。这些设备对象接收请求,并完成实际硬件的功能。
我们可以首先认为:一个真实的设备对应一个设备对象(虽然实际对应关系可能复杂得多)。通过编程可以生成一个虚拟的设备对象,并“绑定”(Attach)在一个真实的设备上。一旦绑定,则本来操作系统发送给真实设备的请求,就会首先发送到这个虚拟设备。
在WDK中,有多个内核API能实现绑定功能。下面是其中一个函数的原型:
NTSTATUS
IoAttachDevice(
IN PDEVICE_OBJECT SourceDevice,
IN PUNICODE_STRING TargetDevice,
OUT PDEVICE_OBJECT *AttachedDevice
);
在绑定一个设备之前,先要知道如何生成一个用于过滤的过滤设备。函数IoCreateDevice被用于生成设备:
NTSTATUS
IoCreateDevice(
IN PDRIVER_OBJECT DriverObject,
IN ULONG DeviceExtensionSize,
IN PUNICODE_STRING DeviceName OPTIONAL,
IN DEVICE_TYPE DeviceType,
IN ULONG DeviceCharacteristics,
IN BOOLEAN Exclusive,
OUT PDEVICE_OBJECT *DeviceObject
);
DriverObject是本驱动的驱动对象。这个指针是系统提供,从DriverEntry中传 入。DeviceExtensionSize是设备扩展,请先简单地传入0。DeviceName是设备名称。一个规则 是:过滤设备一般不需要名称,所以传入NULL即可。DeviceType是设备类型,保持和被绑定的设备类型一致即可。 DeviceCharacteristics是设备特征,在生成设备对象时笔者总是凭经验直接填0,然后看是否排斥,选择FALSE。