基于FilterHookDriver使用ipfirewallh的IP过滤驱动.docx
《基于FilterHookDriver使用ipfirewallh的IP过滤驱动.docx》由会员分享,可在线阅读,更多相关《基于FilterHookDriver使用ipfirewallh的IP过滤驱动.docx(24页珍藏版)》请在冰点文库上搜索。
基于FilterHookDriver使用ipfirewallh的IP过滤驱动
[原创]基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动
文章标题:
[原创]基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动顶部fleshwound发布于:
2007-02-2716:
02[楼主][原创]基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动
文章作者:
fleshwound[smatrix](fleshwound@)
信息来源:
邪恶八进制信息安全团队()
注意:
本文章首发安全矩阵(www.smatrix.org),后由原创作者友情提交到邪恶八进制信息安全团队。
IP过滤驱动可以广泛的应用于网络安全产品的研发,NDIS和TDI的驱动资料很多,有比较成熟的代码可以参考,但是使用IPFIREWALL.h开发的IP过滤驱动的资料非常少,这次自己做一个软件的时候参考VCKBASE上的一篇文章《开发Windows2000/XP下的防火墙》(作者:
JesúsO)的基础上,写了一个驱动,代码都做了详细的注释了,只要稍微有点驱动设计基础的都可以看得懂,我把自己的特殊的回调函数去掉了,保留了基本的完整框架,牛人就不需要看了,初学者都可以在此基础上继续快速开发。
1SmatrixIPDiv.cpp文件
2protocol.h头文件
3SmatrixIPDiv.h头文件
Copycode
/*Copyright(c)2007,安全矩阵(SecurityMatrix)
*Allrightsreserved.
*
*文件名称:
SmatrixIPDiv.cpp
*文件标识:
S
*摘要:
IP过滤驱动,利用ipfirewall捕获包、分析包、过滤包
*开始时间:
2006年12月26Ri
*
*当前版本:
1.0
*作者:
fleshwound@
*相关信息:
http:
//www.smatrix.org
*完成Ri期:
2007年1月2Ri
*/
extern"C"
{
#include
#include
#include
#include
#include
#include
#include
#include
}
#include"SmatrixIPDiv.h"
#include"protocol.h"
/////////////////////////自定义函数的声明///////////////////////
//关闭打开驱动函数
NTSTATUSDispatchCreateClose(PDEVICE_OBJECTpDevObj,PIRPpIrp);
//驱动卸载函数
voidDriverUnload(PDRIVER_OBJECTpDriverObj);
//IO控制派遣函数(内核消息处理)
NTSTATUSDispatchIoctl(PDEVICE_OBJECTpDevObj,PIRPpIrp);
//向过滤列表中添加一个过滤规则
NTSTATUSAddFilterToList(CIPFilter*pFilter);
//清除过滤列表
voidClearFilterList();
//注册钩子回调函数
NTSTATUSSetFilterFunction(IPPacketFirewallPtrfilterFunction,BOOLEANload);
//包过滤函数
FORWARD_ACTIONFilterPacket(unsignedchar*PacketHeader,
unsignedchar*Packet,
unsignedintPacketLength,
DIRECTION_Edirection,
unsignedintRecvInterfaceIndex,
unsignedintSendInterfaceIndex);
//IP过滤器函数
FORWARD_ACTIONIPFilterFunction(VOID**pData,
UINTRecvInterfaceIndex,
UINT*pSendInterfaceIndex,
UCHAR*pDestinationType,
VOID*pContext,
UINTContextLength,
structIPRcvBuf**pRcvBuf);
//过滤列表首地址
structCFilterList*g_pHeader=NULL;
//驱动内部名称和符号连接名称
#defineDEVICE_NAMEL"\\Device\\DevSMFltIP"
#defineLINK_NAMEL"\\DosDevices\\DrvSMFltIp"
//驱动入口函数
NTSTATUSDriverEntry(PDRIVER_OBJECTpDriverObj,PUNICODE_STRINGpRegistryString)
{
NTSTATUSstatus=STATUS_SUCCESS;
//初始化各个派遣例程
pDriverObj->MajorFunction[IRP_MJ_CREATE]=DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_CLOSE]=DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchIoctl;
pDriverObj->DriverUnload=DriverUnload;
//创建、初始化设备对象
//设备名称
UNICODE_STRINGustrDevName;
RtlInitUnicodeString(&ustrDevName,DEVICE_NAME);
//创建设备对象
PDEVICE_OBJECTpDevObj;
status=IoCreateDevice(pDriverObj,
0,
&ustrDevName,
FILE_DEVICE_DRVFLTIP,
0,
FALSE,
&pDevObj);
if(!
NT_SUCCESS(status))
{
returnstatus;
}
//创建符号连接名称
//符号连接名称
UNICODE_STRINGustrLinkName;
RtlInitUnicodeString(&ustrLinkName,LINK_NAME);
//创建关联
status=IoCreateSymbolicLink(&ustrLinkName,&ustrDevName);
if(!
NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
returnstatus;
}
returnSTATUS_SUCCESS;
}
voidDriverUnload(PDRIVER_OBJECTpDriverObj)
{
//卸载过滤函数
SetFilterFunction(IPFilterFunction,FALSE);
//释放所有资源
ClearFilterList();
//删除符号连接名称
UNICODE_STRINGstrLink;
RtlInitUnicodeString(&strLink,LINK_NAME);
IoDeleteSymbolicLink(&strLink);
//删除设备对象
IoDeleteDevice(pDriverObj->DeviceObject);
}
//处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUSDispatchCreateClose(PDEVICE_OBJECTpDevObj,PIRPpIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
//pIrp->IoStatus.Information=0;
//完成此请求
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
returnSTATUS_SUCCESS;
}
//I/O控制派遣例程
NTSTATUSDispatchIoctl(PDEVICE_OBJECTpDevObj,PIRPpIrp)
{
NTSTATUSstatus=STATUS_SUCCESS;
//取得此IRP(pIrp)的I/O堆栈指针
PIO_STACK_LOCATIONpIrpStack=IoGetCurrentIrpStackLocation(pIrp);
//取得I/O控制代码
ULONGuIoControlCode=pIrpStack->Parameters.DeviceIoControl.IoControlCode;
//取得I/O缓冲区指针和它的长度
PVOIDpIoBuffer=pIrp->AssociatedIrp.SystemBuffer;
ULONGuInSize=pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
//响应用户的命令
switch(uIoControlCode)
{
caseSTART_IP_HOOK:
//开始过滤
status=SetFilterFunction(IPFilterFunction,TRUE);
break;
caseSTOP_IP_HOOK:
//停止过滤
status=SetFilterFunction(IPFilterFunction,FALSE);
break;
caseADD_FILTER:
//添加一个过滤规则
if(uInSize==sizeof(CIPFilter))
status=AddFilterToList((CIPFilter*)pIoBuffer);
else
status=STATUS_INVALID_DEVICE_REQUEST;
break;
caseCLEAR_FILTER:
//释放过滤规则列表
ClearFilterList();
break;
default:
status=STATUS_INVALID_DEVICE_REQUEST;
break;
}
//完成请求
pIrp->IoStatus.Status=status;
pIrp->IoStatus.Information=0;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
returnstatus;
}
///////////////////////////////////////////////////////////////////
//过滤列表
//向过滤列表中添加一个过滤规则
NTSTATUSAddFilterToList(CIPFilter*pFilter)
{
//为新的过滤规则申请内存空间
CFilterList*pNew=(CFilterList*)ExAllocatePool(NonPagedPool,sizeof(CFilterList));
if(pNew==NULL)
returnSTATUS_INSUFFICIENT_RESOURCES;
//填充这块内存
RtlCopyMemory(&pNew->ipf,pFilter,sizeof(CIPFilter));
//连接到过滤列表中
pNew->pNext=g_pHeader;
g_pHeader=pNew;
returnSTATUS_SUCCESS;
}
//清除过滤列表
voidClearFilterList()
{
CFilterList*pNext;
//释放过滤列表占用的所有内存
while(g_pHeader!
=NULL)
{
pNext=g_pHeader->pNext;
//释放内存
ExFreePool(g_pHeader);
g_pHeader=pNext;
}
}
//包过滤函数
FORWARD_ACTIONFilterPacket(unsignedchar*PacketHeader,
unsignedchar*Packet,
unsignedintPacketLength,
DIRECTION_Edirection,
unsignedintRecvInterfaceIndex,
unsignedintSendInterfaceIndex)
{
//提取IP头
IPHeader*pIPHdr=(IPHeader*)PacketHeader;
TCPHeader*pTCPHdr=NULL;
UDPHeader*pUDPHdr=NULL;
if(pIPHdr->ipProtocol==6)//是TCP协议
{
//提取TCP头
pTCPHdr=(TCPHeader*)Packet;
//我们接受所有已经建立连接的TCP封包
if(!
(pTCPHdr->flags&0x02))
{
returnFORWARD;
}
}
//与过滤规则相比较,决定采取的行动
CFilterList*pList=g_pHeader;
while(pList!
=NULL)
{
//比较协议
if(pList->ipf.protocol==0||pList->ipf.protocol==pIPHdr->ipProtocol)
{
//查看源IP地址
if(pList->ipf.sourceIP!
=0&
(pList->ipf.sourceIP&pList->ipf.sourceMask)!
=pIPHdr->ipSource)
{
pList=pList->pNext;
continue;
}
//查看目标IP地址
if(pList->ipf.destinationIP!
=0&
(pList->ipf.destinationIP&pList->ipf.destinationMask)!
=pIPHdr->ipDestination)
{
pList=pList->pNext;
continue;
}
//如果是TCP封包,查看端口号
if(pIPHdr->ipProtocol==6)
{
pTCPHdr=(TCPHeader*)Packet;
if(pList->ipf.sourcePort==0||pList->ipf.sourcePort==pTCPHdr->sourcePort)
{
if(pList->ipf.destinationPort==0
||pList->ipf.destinationPort==pTCPHdr->destinationPort)
{
//现在决定如何处理这个封包
if(pList->ipf.bDrop)
returnDROP;
else
returnFORWARD;
}
}
}
//如果是UDP封包,查看端口号
elseif(pIPHdr->ipProtocol==17)
{
pUDPHdr=(UDPHeader*)Packet;
if(pList->ipf.sourcePort==0||pList->ipf.sourcePort==pUDPHdr->sourcePort)
{
if(pList->ipf.destinationPort==0
||pList->ipf.destinationPort==pUDPHdr->destinationPort)
{
//现在决定如何处理这个封包
if(pList->ipf.bDrop)
returnDROP;
else
returnFORWARD;
}
}
}
else
{
//对于其它封包,我们直接处理
if(pList->ipf.bDrop)
returnDROP;
else
returnFORWARD;
}
}
//比较下一个规则
pList=pList->pNext;
}
//我们接受所有没有注册的封包
returnFORWARD;
}
//注册钩子回调函数
NTSTATUSSetFilterFunction(IPPacketFirewallPtrfilterFunction,BOOLEANload)
{
//{变量定义BEGIN}
NTSTATUSstatus=STATUS_SUCCESS;//内核状态
NTSTATUSwaitStatus=STATUS_SUCCESS;//受信状态
PDEVICE_OBJECTpDeviceObj=NULL;//pDeviceObj变量将指向IP过滤驱动设备对象
PFILE_OBJECTpFileObj=NULL;//内核过滤器设备
IP_SET_FIREWALL_HOOK_INFOfilterData;//IP_SET_FIREWALL_HOOK_INFO结构
UNICODE_STRINGustrFilterDriver;//IP过滤驱动的名称
KEVENTevent;//
IO_STATUS_BLOCKioStatus;//
PIRPpIrp;//
//{变量定义END}
//初始化IP过滤驱动的名称
RtlInitUnicodeString(&ustrFilterDriver,DD_IP_DEVICE_NAME);
//取得设备对象指针
status=IoGetDeviceObjectPointer(&ustrFilterDriver,STANDARD_RIGHTS_ALL,&pFileObj,&pDeviceObj);
if(!
NT_SUCCESS(status))
{
returnstatus;
}
///////////使用到IP过滤驱动中设备对象的指针创建一个IRP///////////////////////////
//填充IP_SET_FIREWALL_HOOK_INFO结构
filterData.FirewallPtr=filterFunction;
filterData.Priority=1;
filterData.Add=load;
//我们需要初始化一个事件对象。
//构建IRP时需要使用这个事件内核对象,当IP过滤取得接受到此IRP,完成工作以后会将它置位
KeInitializeEvent(&event,NotificationEvent,FALSE);
//为设备控制请求申请和构建一个IRP
pIrp=IoBuildDeviceIoControlRequest(IOCTL_IP_SET_FIREWALL_HOOK,//iocontrolcode
pDeviceObj,
(PVOID)&filterData,
sizeof(IP_SET_FIREWALL_HOOK_INFO),
NULL,
0,
FALSE,
&event,
&ioStatus);
if(NULL==pIrp)
{
//如果不能申请空间得到pIrp,返回对应的错误代码
returnSTATUS_INSUFFICIENT_RESOURCES;
}
////////////////////////////////////////////////////////////////
///////////////请求安装钩子回调函数/////////////////////////////
//发送此IRP到IP过滤驱动
status=IoCallDriver(pDeviceObj,pIrp);
//等待IP过滤驱动的通知
if(status==STATUS_PENDING)
{
waitStatus=KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
if(!
NT_SUCCESS(waitStatus))//受信状态不成功,返回
{
returnwaitStatus;
}
}
status=ioStatus.Status;
if(!
NT_SUCCESS(status))//状态不成功,返回
{
returnstatus;
}
/////////////////////////////////////////////////////////////////////////
//////////////////////清除内核资源/////////////////////////////////////
if(pFileObj!
=NULL)
ObDereferenceObject(pFileObj);
pDeviceObj=NULL;//避免产生野指针
pFileObj=NULL;//避免产生野指针
returnstatus;
}
//IP过滤器函数
FORWARD_ACTIONIPFilterFunction(VOID**pData,
UINTRecvInterfaceIndex,
UINT*pSendInterfaceIndex,
UCHAR*pDestinationType,
VOID*pContext,
UINTContextLength,
structIPRcvBuf**pRcvBuf)
{
FORWARD_ACTIONresult=FORWARD;
unsignedchar*packet=NULL;
intbufferSize=0;
structIPRcvBuf*buffer=(structIPRcvBuf*)*pData;
PFIREWALL_CONTEXT_TfwContext=(PFIREWALL_CONTEXT_T)pContext;
DIRECTION_Edirection=IP_RECEIVE;
//如果包指针不为空,IPRcvBuf中存在数据
if(buffer!
=NULL)
{
bufferSize=buffer->ipr_size;
while(buffer->ipr_next!
=NULL)//得到整个IPRcvBuf缓冲链中数据总长度
{
buffer=buffer->ipr_next;
bufferSize+=buffer->ip