基于Filter-HookDriver(使用ipfirewallh)的IP过滤驱动.doc_第1页
基于Filter-HookDriver(使用ipfirewallh)的IP过滤驱动.doc_第2页
基于Filter-HookDriver(使用ipfirewallh)的IP过滤驱动.doc_第3页
基于Filter-HookDriver(使用ipfirewallh)的IP过滤驱动.doc_第4页
基于Filter-HookDriver(使用ipfirewallh)的IP过滤驱动.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于Filter-HookDriver(使用ipfirewallh)的IP过滤驱动大漠沙如雪,燕山月似钩。我有迷魂招不得,雄鸡一声天下白。高山仰止,景行行止。同声相应,同气相求。无情未必真豪杰,怜子如何不丈夫。原创基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动文章标题:原创基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动顶部 fleshwound 发布于:2007-02-2716:02 楼主原创基于Filter-HookDriver(使用ipfirewall.h)的IP过滤驱动文章作者:fleshwoundsmatrix()信息来源:邪恶八进制信息安全团队()注意:本文章首发安全矩阵(),后由原创作者友情提交到邪恶八进制信息安全团队。IP过滤驱动可以广泛的应用于网络安全产品的研发,NDIS和TDI的驱动资料很多,有比较成熟的代码可以参考,但是使用IPFIREWALL.h开发的IP过滤驱动的资料非常少,这次自己做一个软件的时候参考VCKBASE上的一篇文章开发Windows2000/XP下的防火墙(作者:JessO)的基础上,写了一个驱动,代码都做了详细的注释了,只要稍微有点驱动设计基础的都可以看得懂,我把自己的特殊的回调函数去掉了,保留了基本的完整框架,牛人就不需要看了,初学者都可以在此基础上继续快速开发。1SmatrixIPDiv.cpp文件2protocol.h头文件3SmatrixIPDiv.h头文件Copycode/*Copyright(c)2007,安全矩阵(SecurityMatrix)*Allrightsreserved.*文件名称:SmatrixIPDiv.cpp*文件标识:S*摘 要:IP过滤驱动,利用ipfirewall捕获包、分析包、过滤包*开始时间:2006年12月26Ri*当前版本:1.0*作 者:*相关信息:*完成Ri期:2007年1月2Ri*/externC #include #include #include #include #include #include #include #include#includeSmatrixIPDiv.h#includeprotocol.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);/过滤列表首地址structCFilterList*g_pHeader=NULL;/驱动内部名称和符号连接名称#defineDEVICE_NAMELDeviceDevSMFltIP#defineLINK_NAMELDosDevicesDrvSMFltIp/驱动入口函数NTSTATUSDriverEntry(PDRIVER_OBJECTpDriverObj,PUNICODE_STRINGpRegistryString) NTSTATUSstatus=STATUS_SUCCESS; /初始化各个派遣例程 pDriverObj-MajorFunctionIRP_MJ_CREATE=DispatchCreateClose; pDriverObj-MajorFunctionIRP_MJ_CLOSE=DispatchCreateClose; pDriverObj-MajorFunctionIRP_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(pLtocol=0|pLtocol=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, 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.htypedefstructIPHeader 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控制代码,用于区分不同的设备控制请

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论