📄 filterpkt.c
字号:
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 + -