#include <string.h>
#include <stdio.h>
#include <ntddk.h>
#include <ntddndis.h>
#include <pfhook.h>
#include "DrvFltIp.h"
#if DBG
#define dprintf DbgPrint
#else
#define dprintf(x)
#endif
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DrvUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS SetFilterFunction(PacketFilterExtensionPtr filterFunction);
NTSTATUS AddFilterToList(IPFilter *pf);
void ClearFilterList(void);
PF_FORWARD_ACTION cbFilterFunction(IN unsigned char *PacketHeader,IN unsigned char *Packet, IN unsigned int PacketLength, IN unsigned int RecvInterfaceIndex, IN unsigned int SendInterfaceIndex, IN unsigned long RecvLinkNextHop, IN unsigned long SendLinkNextHop);
#define NT_DEVICE_NAME L"\\Device\\DrvFltIp"
#define DOS_DEVICE_NAME L"\\DosDevices\\DrvFltIp"
struct filterList *first = NULL;
struct filterList *last = NULL;
/********驱动程序入口点,参数DriverObject表示驱动程序对象的指针,********
*********参数RegistryPath指向注册表中驱动程序键值************************/
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT deviceObject = NULL;
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;
UNICODE_STRING deviceLinkUnicodeString;
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);
if(!NT_SUCCESS(ntStatus))
dprintf("DrvFltIp.SYS: IoCreateSymbolicLink failed\n");
//驱动程序创建、关闭、控制和卸载的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("初始化失败!");
DrvUnload(DriverObject);
}
return ntStatus;
}
//处理IRPs命令
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
PVOID ioBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
ULONG ioControlCode;
NTSTATUS ntStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//获取IRP中当前位置的指针
irpStack = IoGetCurrentIrpStackLocation(Irp);
//获取输入/输出缓冲区及其长度
ioBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
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;
default:
break;
}
ntStatus = Irp->IoStatus.Status;//获取IRP的状态
IoCompleteRequest(Irp, IO_NO_INCREMENT);//调用IoCompleteRequest,则IRP丢失
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);//删除设备对象
}
//获取相关的IpFilterDriver从而安装过滤器
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("获取IpFilterDriver的指针\n");
//获取IpFilterDriver设备的指针
RtlInitUnicodeString(&filterName, DD_IPFLTRDRVR_DEVICE_NAME);
status = IoGetDeviceObjectPointer(&filterName,STANDARD_RIGHTS_ALL, &ipFileObject, &ipDeviceObject);
if(NT_SUCCESS(status))
{
//初始化参数的结构
filterData.ExtensionPointer = filterFunction;
KeInitializeEvent(&event, NotificationEvent, FALSE);
//创建所需的IRP完成过滤器功能
irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, ipDeviceObject,
(PVOID) &filterData,sizeof(PF_SET_EXTENSION_HOOK_INFO),NULL,0,FALSE,&event,&ioStatus);
if(irp != NULL)
{
//发送IRP
status = IoCallDriver(ipDeviceObject, irp);
//等待IpFilterDriver的回应
if (status == STATUS_PENDING)
{
waitStatus = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
if (waitStatus != STATUS_SUCCESS )
dprintf("等待IpFilterDriver回应错误");
}
status = ioStatus.Status;
if(!NT_SUCCESS(status))
dprintf("ipFilterDriver的IO错误\n");
}
else
{
//当无法分配空间时,返回错误
status = STATUS_INSUFFICIENT_RESOURCES;
dprintf("创建IpFilterDriver IRP错误\n");
}
if(ipFileObject != NULL)
ObDereferenceObject(ipFileObject);
ipFileObject = NULL;
ipDeviceObject = NULL;
}
else
dprintf("获取指针时出现错误\n");
return status;
}
//在过滤器列表中添加规则
NTSTATUS AddFilterToList(IPFilter *pf)
{
struct filterList *aux=NULL;
//为新的过滤器分配内存
aux=(struct filterList*)ExAllocatePool(NonPagedPool, sizeof(struct filterList));
if(aux == NULL)
{
dprintf("内存分配问题\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
//定义结构成员的属性值
aux->ipf.destinationIp = pf->destinationIp;
aux->ipf.sourceIp = pf->sourceIp;
aux->ipf.destinationMask = pf->destinationMask;
aux->ipf.sourceMask = pf->sourceMask;
aux->ipf.destinationPort = pf->destinationPort;
aux->ipf.sourcePort = pf->sourcePort;
aux->ipf.protocol = pf->protocol;
aux->ipf.drop=pf->drop;
//在过滤器列表中添加新的过滤器
if(first == NULL)
{
first = last = aux;
first->next = NULL;
}
else
{
last->next = aux;
last = aux;
last->next = NULL;
}
dprintf("Rule Added\n\t%x %x\n\t%x %x\n\t%x\n\t%x", aux->ipf.sourceIp,
aux->ipf.sourceMask,aux->ipf.destinationIp, aux->ipf.destinationMask,
aux->ipf.sourcePort, aux->ipf.destinationPort);
return STATUS_SUCCESS;
}
//去除保存的规则的连接表
void ClearFilterList(void)
{
struct filterList *aux = NULL;
//释放连接表
dprintf("Removing the filter List...");
while(first != NULL)
{
aux = first;
first = first->next;
ExFreePool(aux);
dprintf("One Rule removed");
}
first = last = NULL;
dprintf("Removed is complete.");
}
//过滤收到或发送的包
PF_FORWARD_ACTION cbFilterFunction(IN unsigned char *PacketHeader,IN unsigned char *Packet, IN unsigned int Packet
我虽横行却不霸道
- 粉丝: 95
- 资源: 1万+
最新资源
- NSKeyValueObservationException如何解决.md
- 基于Java的环境保护与宣传网站论文.doc
- 前端开发中的JS快速排序算法原理及实现方法
- 常见排序算法概述及其性能比较
- 形状分类31-YOLO(v5至v11)、COCO、CreateML、Darknet、Paligemma、VOC数据集合集.rar
- 2018年最新 ECshop母婴用品商城新版系统(微商城+微分销+微信支付)
- BookShopTuto.zip
- 论文复现:结合 CNN 和 LSTM 的滚动轴承剩余使用寿命预测方法
- MySQL中的数据库管理语句-ALTER USER.pdf
- 冒泡排序算法解析及优化.md
- 2024年智算云市场发展与生态分析报告
- qwewq23132131231
- 《木兰诗》教学设计.docx
- 《台阶》教学设计.docx
- 《卖油翁》文言文教学方案.docx
- 《老王》教学设计方案.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论1