在上面的代码中,你已经看到了SetFilterFunction(..)函数。我在IP Filter Driver中执行这个函数来注册过滤函数,步骤如下:
1) 首先,我们必须得到IP Filter Driver的指针,这要求驱动已经安装并执行。为了保证IP Filter Driver已经安装并执行,在我的用户程序中,在加载本驱动前加载并启动IP Filter Driver。
2) 第二步,我们必须建立用IOCTL_PF_SET_EXTENSION_POINTER作为控制代码的IRP。我们必须传递PF_SET_EXTENSION_HOOK_INFO 参数,该参数结构中包含了指向过滤函数的指针。如果你要卸载该函数,你必须在同样的步骤里传递NULL作为过滤函数指针。
3) 向设备驱动发送创建IRP, 这里有一个大的问题,只有一个过滤函数可以安装,因此如果另外的应用程序已经安装了一个过滤函数,你就不能再安装了。
设置过滤函数的代码如下:
| NTSTATUS SetFilterFunction (PacketFilterExtensionPtr filterFunction) { NTSTATUS status = STATUS_SUCCESS, waitStatus=STATUS_SUCCESS; UNICODE_STRING filterName; PDEVICE_OBJECT ipDeviceObject=NULL; PFILE_OBJECT ipFileObject=NULL; PF_SET_EXTENSION_HOOK_INFO filterData; KEVENT event; IO_STATUS_BLOCK ioStatus; PIRP irp; dprintf("Getting pointer to IpFilterDriver\n"); //首先我们要得到IpFilterDriver Device的指针 RtlInitUnicodeString(&filterName, DD_IPFLTRDRVR_DEVICE_NAME); status = IoGetDeviceObjectPointer(&filterName,STANDARD_RIGHTS_ALL, &ipFileObject, &ipDeviceObject); if(NT_SUCCESS(status)) { //用过滤函数作为参数初始化PF_SET_EXTENSION_HOOK_INFO结构 filterData.ExtensionPointer = filterFunction; //我们需要初始化事件,用于在完成工作后通知我们 KeInitializeEvent(&event, NotificationEvent, FALSE); //创建用于设立过滤函数的IRP irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, ipDeviceObject, { // 发送 IRP status = IoCallDriver(ipDeviceObject, irp); // 然后我们等待IpFilter Driver的回应 if (status == STATUS_PENDING) { waitStatus = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); if (waitStatus != STATUS_SUCCESS ) dprintf("Error waiting for IpFilterDriver response."); } status = ioStatus.Status; if(!NT_SUCCESS(status)) dprintf("Error, IO error with ipFilterDriver\n"); } else { //如果不能分配空间,返回相应的错误代码 status = STATUS_INSUFFICIENT_RESOURCES; dprintf("Error building IpFilterDriver IRP\n"); } if(ipFileObject != NULL) ObDereferenceObject(ipFileObject); ipFileObject = NULL; ipDeviceObject = NULL; } else dprintf("Error while getting the pointer\n"); return status; } |
当我们已经完成了建立过滤函数的工作,当取得设备驱动的指针后必须释放文件对象。我使用事件来通知IpFilter Driver 已经完成了IRP处理。