文档库 最新最全的文档下载
当前位置:文档库 › 基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动

基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动

[原创]基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动
文章标题:[原创]基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动顶部 fleshwound 发布于:2007-02-2716:02 [楼主][原创]基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动
文章作者:fleshwound[smatrix](fleshwound@https://www.wendangku.net/doc/8f6122506.html,)
信息来源:邪恶八进制信息安全团队(https://www.wendangku.net/doc/8f6122506.html,)

注意:本文章首发安全矩阵(https://www.wendangku.net/doc/8f6122506.html,),后由原创作者友情提交到邪恶八进制信息安全团队。

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@https://www.wendangku.net/doc/8f6122506.html,
*相关信息:https://www.wendangku.net/doc/8f6122506.html,
*完成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,
UINT RecvInterfaceIndex,
UINT *pSendInterfaceIndex,
UCHAR *pDestinationType,
VOID *pContext,
UINT ContextLength,
structIPRcvBuf**pRcvBuf);
//过滤列表首地址
structC

FilterList*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->https://www.wendangku.net/doc/8f6122506.html,rmation=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->https://www.wendangku.net/doc/8f6122506.html,rmation=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.bD

rop)
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,
UINT RecvInterfaceIndex,
UINT *pSendInterfaceIndex,
UCHAR *pDestinationType,
VOID *pContext,
UINT ContextLength,
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->ipr_size;
}

//分配一个不分页的内存,将整个IPRcvBuf缓冲链放入其中
packet=(unsignedchar*)ExAllocatePool(NonPagedPool,bufferSize);
if(packet!=NULL)
{
IPHeader*ipp=(IPHeader*)packet;
unsignedintoffset=0;

buffer=(structIPRcvBuf*)*pData;

memcpy(packet,buffer->ipr_buffer,buffer->ipr_size);

while(buffer->ipr_next!=NULL)
{
offset+=buffer->ipr_size;
buffer=buffer->ipr_next;

memcpy(packet+offset,buffer->ipr_buffer,buffer->ipr_size);
}
if(NULL!=fwContext)
{
direction=fwContext->Direction;
}
else
{
direction=(DIRECTION_E)0;
}

//调用包检测函数,通过返回FORWARD,否则返回DROP
result=FilterPacket(packet,
packet+(ipp->ipHeaderLength*4),
bufferSize-(ipp->ipHeaderLength*4),
direction,
RecvInterfaceIndex,
(pSendInterfaceIndex!=NULL)?*pSendInterfaceIndex:0);


}


}

//释放分配的临时包缓存
if(NULL!=packet)ExFreePool(packet);

returnresult;
}

2定义常见的封包结构信息

Copycode
//文件名称:protocol.h

typedefstructIPHeader
{ UCHAR ipHeaderLength:4; //头长度
UCHAR ipVersion:4; //版本号
UCHAR ipTOS; //服务类型
USHORT ipLength; //封包总长度,即整个IP报的长度
USHORT ipID; //封包标识,惟一标识发送的每一个数据报
USHORT ipFlags; //标志
UCHAR ipTTL; //生存时间,就是TTL
UCHAR ipProtocol; //协议,可能是TCP、UDP、ICMP等
USHORT ipChecksum; //校验和
ULONG ipSource; //源IP地址
ULONG ipDestination;//目标IP地址
}IPPacket;


typedefstruct_TCPHeader
{
USHORT sourcePort; //源端口号
USHORT destinationPort; //目的端口号
ULONG sequenceNumber; //序号
ULONG acknowledgeNumber; //确认序号
UCHAR dataoffset; //数据指针
UCHAR flags; //标志
USHORT windows; //窗口大小
USHORT checksum; //校验和
USHORT urgentPointer; //紧急指针
}TCPHeader;

typedefstruct_UDPHeader
{
USHORT sourcePort; //源

端口号
USHORT destinationPort; //目的端口号
USHORT len; //封包长度
USHORT checksum; //校验和
}UDPHeader;
enum
{
IPPROTO_IP =0, //DummyprotocolforTCP.
IPPROTO_HOPOPTS =0, //IPv6Hop-by-Hopoptions.*/
IPPROTO_ICMP =1, //InternetControlMessageProtocol.*/
IPPROTO_IGMP =2, //InternetGroupManagementProtocol.*/
IPPROTO_IPIP =4, //IPIPtunnels(olderKA9Qtunnelsuse94).*/
IPPROTO_TCP =6, //TransmissionControlProtocol.*/
IPPROTO_EGP =8, //ExteriorGatewayProtocol.*/
IPPROTO_PUP =12, // PUPprotocol.*/
IPPROTO_UDP =17, // UserDatagramProtocol.*/
IPPROTO_IDP =22, //XNSIDPprotocol.*/
IPPROTO_TP =29, //SOTransportProtocolClass4.*/
IPPROTO_IPV6 =41, // IPv6header.*/
IPPROTO_ROUTING =43, // IPv6routingheader.*/
IPPROTO_FRAGMENT =44, // IPv6fragmentationheader.*/
IPPROTO_RSVP =46, //ReservationProtocol.*/
IPPROTO_GRE =47, //GeneralRoutingEncapsulation.*/
IPPROTO_ESP =50, //encapsulatingsecuritypayload.*/
IPPROTO_AH =51, //authenticationheader.*/
IPPROTO_ICMPV6 =58, //ICMPv6.*/
IPPROTO_NONE =59, /*IPv6nonextheader.*/
IPPROTO_DSTOPTS =60, /*IPv6destinationoptions.*/
IPPROTO_MTP =92, /*MulticastTransportProtocol.*/
IPPROTO_ENCAP =98, /*EncapsulationHeader.*/
IPPROTO_PIM =103, /*ProtocolIndependentMulticast.*/
IPPROTO_COMP =108, /*CompressionHeaderProtocol.*/
IPPROTO_RAW =255, /*RawIPpackets.*/
IPPROTO_MAX
};

3IP过滤驱动相关结构和宏定义

Copycode
//文件名称:SmatrixIPDiv.h
#ifndef__SMATRIXIPDIV_H__
#define__SMATRIXIPDIV_H__

//自定义设备类型,在创建设备对象时使用
//注意,自定义值的范围是32768-65535
#defineFILE_DEVICE_DRVFLTIP0x00654322

//自定义的IO控制代码,用于区分不同的设备控制请求
//注意,自定义值的范围是2048-4095
#defineDRVFLTIP_IOCTL_INDEX0x830

//
//定义各种设备控制代码。分别是开始过滤、停止过滤、添加过滤规则、清除过滤规则
//
#defineSTART_IP_HOOK CTL_CODE(FILE_DEVICE_DRVFLTIP,\
DRVFLTIP_IOCTL_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)
#defineSTOP_IP_HOOK CTL_CODE(FILE_DEVICE_DRVFLTIP,\
DRVFLTIP_IOCTL_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)
#defineADD_FILTER CTL_CODE(FILE_DEVICE_DRVFLTIP,\
DRVFLTIP_IOCTL_INDEX+2,METHOD_BUFFERED,FILE_WRITE_ACCESS)
#defineCLEAR_FILTER CTL_CODE(FILE_DEVICE_DRVFLTIP,\
DRVFLTIP_IOCTL_INDEX+3,METHOD_BUFFERED,FILE_ANY_ACCESS)

//定义过滤规则的结构
structCIPFilter
{
USHORTprotocol; //使用的协议

ULONGsourceIP; //源IP地址
ULONGdestinationIP; //目标IP地址

ULONGsourceMask; //源地址屏蔽码
ULONGdestinationMask; //目的地址屏蔽码

USHORTsourcePort; //源端口号
USHORTdestinationPort; //目的端口号

BOOLEANbDrop; //是否丢弃此封包
};

//过滤列表
structCFilterList
{

CIPFilteripf; //过滤规则
CFilterList*pNext; //指向下一个CFilterList结构
};

#endif//__SMATRIXIPDIV_H__

注:这里感谢下sinister和驱动网若干牛人的热情指导和建议,需要驱动开发向导文件得可以到https://www.wendangku.net/doc/8f6122506.html,/bbs下。
byfleshwound

参考文献:
1开发Windows2000/XP下的防火墙,https://www.wendangku.net/doc/8f6122506.html,/document/viewdoc/?id=1067(c)Copyleft2003-2007,EvilOctalSecurityTeam.
ThisfileisdecompiledbyanunregisteredversionofChmDecompiler.
Regsiteredversiondoesnotshowthismessage.
YoucandownloadChmDecompilerat:https://www.wendangku.net/doc/8f6122506.html,/


相关文档
相关文档 最新文档