⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filterpkt.c

📁 一个截取网络包的驱动。它与DDK文档正是NDIS中间驱动不同
💻 C
📖 第 1 页 / 共 3 页
字号:

	return NDIS_STATUS_NOT_ACCEPTED;
}

static SProcessPkt g_ProcessPkts[MAX_PP];
static SStopProc g_CurStopProc;

//创建通知客户端Event句柄
#ifdef _WIN32_WINNT
PKEVENT g_StopProcEvent=NULL;
HANDLE	g_hStopProcHandle=NULL;
HANDLE	g_hVDialProcID=NULL;
void CreateStopProcEvent()
{
	UNICODE_STRING		   uszStopProcEventString;

	if(g_StopProcEvent==NULL)
	{
		RtlInitUnicodeString(&uszStopProcEventString, L"\\BaseNamedObjects\\StopProcEvent");
		g_StopProcEvent=IoCreateNotificationEvent(&uszStopProcEventString, &g_hStopProcHandle);
		KeClearEvent(g_StopProcEvent);

		g_hVDialProcID=PsGetCurrentProcessId();
	}

	DbgPrint("CreateStopProcEvent g_StopProcEvent=%X g_hVDialProcID=%X\n",
		g_StopProcEvent,g_hVDialProcID);
}
#else
HANDLE g_StopProcEvent=NULL;
void CreateStopProcEvent(HANDLE hStopProcEvent)
{
	if(g_StopProcEvent) _VWIN32_CloseVxDHandle(g_StopProcEvent);
	g_StopProcEvent=hStopProcEvent;

	DbgPrint("CreateStopProcEvent g_StopProcEvent=%X\n",g_StopProcEvent);
}
#endif

//通知客户端
void NotifyStopProc(const char *szStopProc,ULONG uWhy)
{
	if(g_StopProcEvent)
	{
		if(szStopProc)
		{
			strncpy(g_CurStopProc.szName,szStopProc,sizeof(g_CurStopProc.szName)-1);
			g_CurStopProc.szName[sizeof(g_CurStopProc.szName)-1]=0;
		}
		else
		{
			g_CurStopProc.szName[0]=0;
		}
		g_CurStopProc.uWhy=uWhy;
#ifdef _WIN32_WINNT
		KeSetEvent(g_StopProcEvent, 0, FALSE);
		KeClearEvent(g_StopProcEvent);
		DbgPrint("NotifyStopProc KeSetEvent Stop Proc=%s g_StopProcEvent=%X\n",
			g_CurStopProc.szName,g_StopProcEvent);
#else
		_VWIN32_SetWin32Event(g_StopProcEvent);
		DbgPrint("NotifyStopProc _VWIN32_SetWin32Event Stop Proc=%s g_StopProcEvent=%X\n",
			g_CurStopProc.szName,g_StopProcEvent);
#endif
	}
}

//发送中毒进程通知给客户端
void SendStopProc(const char *szStopProc,ULONG uWhy,PNDIS_PACKET outPacket)
{
	ULONG uRead;

	if(memcmp(g_onlinemac,g_nullmac,6)==0)
	{
		ReadOnPacket(outPacket,g_onlinemac,sizeof(g_onlinemac),6,&uRead);
	}

	if(g_onlineip==0)
	{
		ReadOnPacket(outPacket,(UCHAR*)&g_onlineip,sizeof(g_onlineip),sizeof(SEth)+12,&uRead);
	}

	SendAllBindVDPacket(NOTIFY_STOPPROC,g_mydhcp.AsMac,0x58585858,szStopProc);
	NotifyStopProc(szStopProc,uWhy);
}

//按照进程名szProcess取该进程发包结构,如果没有增加该进程名,如果缓冲区不够,返回NULL
SProcessPkt* GetProcessPkt(const char *szProcess)
{
	int i;
	ULONG uCurTime;

	for(i=0;i<MAX_PP;i++)
	{
		if(strncmp(g_ProcessPkts[i].szProcess,szProcess,MAX_PNAME_LEN)==0)
		{
			return &g_ProcessPkts[i];
		}
	}

	uCurTime=GetMSTime();

	for(i=0;i<MAX_PP;i++)
	{
		if( ( (uCurTime-g_ProcessPkts[i].uIpCheckTime>=180000) || (g_ProcessPkts[i].uIpCheckTime==0) ) &&
			(g_ProcessPkts[i].nIpStatus==PPS_IP_COMMON) &&
			(g_ProcessPkts[i].nArpStatus==PPS_ARP_COMMON) &&
			(g_ProcessPkts[i].nPktStatus==PPS_PKT_COMMON) )
		{
			g_ProcessPkts[i].uIpPktNum=g_ProcessPkts[i].uIpIpNum=g_ProcessPkts[i].uArpIpNum=g_ProcessPkts[i].uPktPktNum=0;
			strncpy(g_ProcessPkts[i].szProcess,szProcess,MAX_PNAME_LEN);
			return &g_ProcessPkts[i];
		}
	}

	return NULL;
}

//检测某进程发包个数情况
void DoProcPktPkt(PNDIS_PACKET outPacket,SProcessPkt* pProcessPkt)
{
	ULONG uCurTime=GetMSTime();
	ULONG uOffTime=uCurTime-pProcessPkt->uPktCheckTime;

	//上线并且没有发向网关的包不与统计
	if(g_bOnline)
	{
		ULONG uRead;
		UCHAR dmac[6];
		ReadOnPacket(outPacket,dmac,sizeof(dmac),0,&uRead);
		if(!IsBroadcastExMac(dmac) && memcmp(dmac,g_gwmac,6)!=0)
		{
			return;
		}
	}

	//CHECK_TIME时间内,发不少于MAX_PKT个包则认为有问题
	if(uOffTime<CHECK_TIME)
	{
		if(pProcessPkt->uPktPktNum<0xFFFF) pProcessPkt->uPktPktNum++;

		if(pProcessPkt->uPktPktNum>=MAX_PKT)
		{
			DbgPrint("Stop %s for pkt\n",pProcessPkt->szProcess);
			pProcessPkt->nPktStatus=PPS_PKT_STOP;
			SendStopProc(pProcessPkt->szProcess,SPWHY_PKT,outPacket);
		}
	}
	else
	{
		pProcessPkt->uPktPktNum=0;
		pProcessPkt->uPktCheckTime=uCurTime;
	}
}

#define	ETH_ARP		0x0608
#define	ETH_IP		0x0008

//检测某进程发ARP包的目标IP情况
void DoProcArpPkt(PNDIS_PACKET outPacket,SProcessPkt* pProcessPkt)
{
	ULONG uCurTime=GetMSTime();
	ULONG uOffTime=uCurTime-pProcessPkt->uArpCheckTime;

	ULONG uTIp=0,uRead;

	ReadOnPacket(outPacket,(UCHAR*)&uTIp,sizeof(uTIp),38,&uRead);

	if(uTIp)
	{
		int nPos;

		uTIp=UTIL_htonl(uTIp);

		if(uOffTime<CHECK_TIME)
		{
			ArrayAddU32((ULONG(*)[])&pProcessPkt->uArpIps,
				uTIp,&pProcessPkt->uArpIpNum,&nPos,MAX_ARP);

			//CHECK_TIME时间内,发不少于MAX_ARP个不同目标IP则认为有问题
			if(pProcessPkt->uArpIpNum>=MAX_ARP)
			{
				DbgPrint("Stop %s for arp\n",pProcessPkt->szProcess);
				pProcessPkt->nArpStatus=PPS_ARP_STOP;
				SendStopProc(pProcessPkt->szProcess,SPWHY_ARP,outPacket);
			}
		}
		else
		{
			pProcessPkt->uArpIpNum=0;
			pProcessPkt->uArpCheckTime=uCurTime;
			ArrayAddU32((ULONG(*)[])&pProcessPkt->uArpIps,
				uTIp,&pProcessPkt->uArpIpNum,&nPos,MAX_ARP);
		}
	}
}

//辅助函数:计算个数为uIpNum的IP数组uIps,3个最多B类地址的个数
int CalcIpSeg(ULONG uIps[],USHORT uIpNum,int *pMax1,int *pMax2,int *pMax3)
{
	USHORT u;
	ULONG uCurIpSeg=uIps[0]&0xFFFF0000;
	int nCurIpSegNum=1;

	*pMax1=*pMax2=*pMax3=0;

	for(u=1;u<uIpNum;u++)
	{
		if((uIps[u]&0xFFFF0000)==uCurIpSeg)
		{
			nCurIpSegNum++;
		}
		else
		{
			if(nCurIpSegNum>*pMax1)
			{
				*pMax3=*pMax2;
				*pMax2=*pMax1;
				*pMax1=nCurIpSegNum;
			}
			else if(nCurIpSegNum>*pMax2)
			{
				*pMax3=*pMax2;
				*pMax2=nCurIpSegNum;
			}
			else if(nCurIpSegNum>*pMax3)
			{
				*pMax3=nCurIpSegNum;
			}

			uCurIpSeg=uIps[u]&0xFFFF0000;
			nCurIpSegNum=1;
		}
	}

	//最后检查
	if(nCurIpSegNum>*pMax1)
	{
		*pMax3=*pMax2;
		*pMax2=*pMax1;
		*pMax1=nCurIpSegNum;
	}
	else if(nCurIpSegNum>*pMax2)
	{
		*pMax3=*pMax2;
		*pMax2=nCurIpSegNum;
	}
	else if(nCurIpSegNum>*pMax3)
	{
		*pMax3=nCurIpSegNum;
	}

	return 0;
}

//检测某进程发IP包的目标IP情况
void DoProcIpPkt(PNDIS_PACKET outPacket,SProcessPkt* pProcessPkt)
{
	ULONG uCurTime=GetMSTime();
	ULONG uOffTime=uCurTime-pProcessPkt->uIpCheckTime;

	switch(pProcessPkt->nIpStatus)
	{
	case PPS_IP_COMMON:
		if(uOffTime>2000)
		{
			pProcessPkt->uIpPktNum=1;
			pProcessPkt->uIpCheckTime=uCurTime;
		}
		else
		{
			//2000毫秒内多于2000个包进入PPS_IP_CHECK状态
			if(++pProcessPkt->uIpPktNum>=2000)
			{
				DbgPrint("Check %s for ip\n",pProcessPkt->szProcess);
				pProcessPkt->nIpStatus=PPS_IP_CHECK;
				pProcessPkt->uIpCheckTime=uCurTime;
				pProcessPkt->uIpIpNum=0;
			}
		}
		break;
	case PPS_IP_CHECK:
		if(uOffTime>CHECK_TIME)
		{
			pProcessPkt->nIpStatus=PPS_IP_COMMON;
			pProcessPkt->uIpIpNum=pProcessPkt->uIpPktNum=0;
		}
		else
		{
			ULONG uTIp=0,uRead;

			ReadOnPacket(outPacket,(UCHAR*)&uTIp,sizeof(uTIp),30,&uRead);

			if(uTIp)
			{
				int nPos;

				uTIp=UTIL_htonl(uTIp);
				ArrayAddU32((ULONG(*)[])&pProcessPkt->uIpIps,
					uTIp,&pProcessPkt->uIpIpNum,&nPos,MAX_TIP);

//				DbgPrint("Proc=%s IpIpNum=%d\n",pProcessPkt->szProcess,pProcessPkt->uIpIpNum);
				if(pProcessPkt->uIpIpNum>=MAX_TIP)
				{
					int nMax1,nMax2,nMax3;
					CalcIpSeg(pProcessPkt->uIpIps,pProcessPkt->uIpIpNum,&nMax1,&nMax2,&nMax3);
					DbgPrint("Find %s for ip,%d %d %d\n",pProcessPkt->szProcess,nMax1,nMax2,nMax3);
					//不同目标IP多于MAX_TIP并且最大的3个B类地址总和多于(MAX_TIP*2/3),则禁止该进程一段时间
					if((nMax1+nMax2+nMax3)>=(MAX_TIP*2/3))
					{
						pProcessPkt->nIpStatus=PPS_IP_STOP;
						SendStopProc(pProcessPkt->szProcess,SPWHY_IP,outPacket);
					}
					else
					{
						pProcessPkt->uIpCheckTime=uCurTime;
						pProcessPkt->uIpIpNum=0;	//重新Check
					}
				}
			}
		}
		break;
	}
}

//主过滤发送函数
int FilterSend(PNDIS_PACKET outPacket)
{
	UINT uLen;
	char *szProcess;
	SProcessPkt* pProcessPkt;
	USHORT uProto=0;
	ULONG uRead;

	if(!RecvMyDhcp()) return 0;

	if(LimitProxy())
	{
		UCHAR dmac[6];
		ReadOnPacket(outPacket,dmac,sizeof(dmac),0,&uRead);
		//记录发送本机广播包的最近时间
		if(IsBroadcastExMac(dmac))
		{
//			DbgPrint("FilterSend broadcastmac or multicastmac");
			g_sendbrdtm=GetMSTime();
		}
	}

	NdisQueryPacket(outPacket,NULL,NULL,NULL,&uLen);
	if(uLen>=256) return 0;		//只检测小包

	ReadOnPacket(outPacket,(UCHAR*)&uProto,sizeof(uProto),12,&uRead);
	if(uProto==ETH_IP)
	{
		ULONG uTIp;
		ReadOnPacket(outPacket,(UCHAR*)&uTIp,sizeof(uTIp),30,&uRead);
		if(uTIp==g_mydhcp.uHomepageIp || uTIp==0x58585858) return 0;	//首页和认证包除外
	}

	if((szProcess=GetProcessName())==NULL) return 0;
	if(strcmp(SYSNAME,szProcess)==0) return 0;

	if((pProcessPkt=GetProcessPkt(szProcess))==NULL) return 0;

#define	IP_STOPTIME		300000
#define	ARP_STOPTIME	60000
#define	PKT_STOPTIME	600000

	if(pProcessPkt->nIpStatus==PPS_IP_STOP)
	{
		//时间超过IP_STOPTIME解禁,否则丢包
		if(GetMSTime()-pProcessPkt->uIpCheckTime>IP_STOPTIME)
		{
			pProcessPkt->nIpStatus=PPS_IP_COMMON;
			pProcessPkt->uIpIpNum=pProcessPkt->uIpPktNum=0;
		}
		else
		{
			return 1;
		}
	}

	if(pProcessPkt->nArpStatus==PPS_ARP_STOP)
	{
		//时间超过ARP_STOPTIME解禁,否则非网关包丢弃
		if(GetMSTime()-pProcessPkt->uArpCheckTime>ARP_STOPTIME)
		{
			pProcessPkt->nArpStatus=PPS_ARP_COMMON;
			pProcessPkt->uArpIpNum=0;
		}
		else if(uProto==ETH_ARP)
		{
			UAddr uaddr;
			ReadOnPacket(outPacket,(UCHAR*)&uaddr.uIp,sizeof(uaddr.uIp),38,&uRead);
			if(uaddr.uIp!=g_gwip && uaddr.sIp.d!=1 && uaddr.sIp.d!=254) return 1;
		}
	}

	if(pProcessPkt->nPktStatus==PPS_PKT_STOP)
	{
		//时间超过PKT_STOPTIME解禁,否则丢弃
		if(GetMSTime()-pProcessPkt->uPktCheckTime>PKT_STOPTIME)
		{
			pProcessPkt->nPktStatus=PPS_PKT_COMMON;
			pProcessPkt->uPktPktNum=0;
		}
		else
		{
			return 1;
		}
	}

	DoProcPktPkt(outPacket,pProcessPkt);	//检测包个数

	switch(uProto)
	{
	case ETH_ARP:
		DoProcArpPkt(outPacket,pProcessPkt);		//检测ARP包
		break;
	case ETH_IP:
		DoProcIpPkt(outPacket,pProcessPkt);		//检测IP包
		break;
	default:
		break;
	}

	return 0;
}

//接收客户端设置
void DevCtrl(ULONG uCode,void *pInBuf,void *pOutBuf,ULONG *pRetLen)
{
	UCHAR *pMac=(UCHAR*)pInBuf;
	ULONG *pIp=(ULONG*)pInBuf;
	long *pVer=(long*)pOutBuf;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -