创建内核模式驱动(Kernel Mode Driver)
Filter-Hook Driver属于内核模式驱动,因此我们要创建内核模式驱动。这篇文章不是“如何仅用5分钟开发内核模式驱动” 这样的指南,因此我假设读者已经有了关于此的相关知识。
Filter-Hook Driver结构是典型的内核模式驱动的结构:
1) 一个创建设备的驱动程序入口,为通讯创建符号连接和处理IRPs(分派,加载,卸载,创建...)的标准例程。
2)在标准例程里管理IRPs.在开始编码前,我建议先思考一下哪些IOCTL你需要从设备驱动中暴露给应用程序。 在我的例子中,我实现了四个IOCTL代码:START_IP_HOOK(注册过滤函数),STOP_IP_HOOK(注销过滤函数), ADD_FILTER(安装新的过滤规则),CLEAR_FILTER(清除所有规则).
3)对于我们的驱动,我们必须实现多个用于过滤的函数。
我推荐你使用工具程序来产生内核驱动基本框架,这样你只需往里添加代码。例如,我在工程中使用的是QuickSYS。
下面是驱动结构的实现代码:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {
//....
dprintf("DrvFltIp.SYS: entering DriverEntry\n");
//我们必须创建设备 RtlInitUnicodeString(&deviceNameUnicodeString, NT_DEVICE_NAME);
ntStatus = IoCreateDevice(DriverObject, 0, &deviceNameUnicodeString, FILE_DEVICE_DRVFLTIP, 0, FALSE, &deviceObject);
if ( NT_SUCCESS(ntStatus) ) { // 创建符号连接使win32应用程序可以处理驱动与设备 RtlInitUnicodeString(&deviceLinkUnicodeString, DOS_DEVICE_NAME);
ntStatus = IoCreateSymbolicLink(&deviceLinkUnicodeString, &deviceNameUnicodeString);
//....
// 创建用于控制、创建、关闭的dispatch指针
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DrvDispatch; DriverObject->DriverUnload = DrvUnload; }
if ( !NT_SUCCESS(ntStatus) ) { dprintf("Error in initialization. Unloading...");
DrvUnload(DriverObject); }
return ntStatus; }
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
// ....
switch (irpStack->MajorFunction) { case IRP_MJ_CREATE:
dprintf("DrvFltIp.SYS: IRP_MJ_CREATE\n");
break;
case IRP_MJ_CLOSE:
dprintf("DrvFltIp.SYS: IRP_MJ_CLOSE\n");
break;
case IRP_MJ_DEVICE_CONTROL:
dprintf("DrvFltIp.SYS: IRP_MJ_DEVICE_CONTROL\n");
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (ioControlCode) { // 启动过滤的ioctl代码 case START_IP_HOOK: { SetFilterFunction(cbFilterFunction);
break; }
// 关闭过滤的ioctl case STOP_IP_HOOK: { SetFilterFunction(NULL);
break; }
// 添加过滤规则的ioctl case ADD_FILTER: { if(inputBufferLength == sizeof(IPFilter)) { IPFilter *nf;
nf = (IPFilter *)ioBuffer;
AddFilterToList(nf); }
break; }
// 释放过滤规则列表的ioctl case CLEAR_FILTER: { ClearFilterList();
break; }
default: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
dprintf("DrvFltIp.SYS: unknown IRP_MJ_DEVICE_CONTROL\n");
break; }
break; }
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
// 我们不会有未决的操作,所以总是返回状态码 return ntStatus; }
VOID DrvUnload(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING deviceLinkUnicodeString;
dprintf("DrvFltIp.SYS: Unloading\n");
SetFilterFunction(NULL);
// 释放所有资源 ClearFilterList();
// 删除符号连接 RtlInitUnicodeString(&deviceLinkUnicodeString, DOS_DEVICE_NAME); IoDeleteSymbolicLink(&deviceLinkUnicodeString);
// 删除设备对象 IoDeleteDevice(DriverObject->DeviceObject); } |
我们已经编写了驱动的主代码,下面我们继续实现Filter-Hook Driver
|