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

📄 sniffer.cpp

📁 主要是关于贪吃蛇算法在QQ通信中应用.使用VC++6.0.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"
#include ".\sniffer.h"
#include "mstcpip.h"  
#include "openssl/md5.h"
#include "crypt.h"



CSniffer::CSniffer(void)
{
	_snprintf(TcpFlag,6,"FSRPAU");
	ParamTcp =false; // -t关注TCP 报文  
	ParamUdp =false; // -u关注UDP 报文  
	ParamIcmp =false; // -i关注ICMP报文  
	ParamDecode=true; // -d对协议进行解码  
	strFromIpFilter=NULL; // 源IP地址过滤  
	strDestIpFilter=NULL; // 目的地址过滤  
	m_inited=false;
	WSADATA wsaData;  
	WSAStartup(MAKEWORD(2,1),&wsaData); 
}

CSniffer::~CSniffer(void)
{
}

int CSniffer::Start()
{
	int iErrorCode;  
	char RecvBuf[MAX_PACK_LEN] = { 0 }; 
	ParamUdp=true;
	if(!m_inited){
		return -4;
	}
	
	SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP);

	char FAR name[MAX_HOSTNAME_LAN];  
	iErrorCode = gethostname(name, MAX_HOSTNAME_LAN); 
	if(SOCKET_ERROR == iErrorCode){
		WSACleanup();
		return -1;
	}

	struct hostent FAR * pHostent;
	SOCKADDR_IN sa;
	pHostent = gethostbyname(name); 
	sa.sin_family = AF_INET;  
	sa.sin_port = htons(6000);
	memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);  
	iErrorCode = bind(SockRaw, (PSOCKADDR)&sa, sizeof(sa));
	if(0!=iErrorCode){
		WSACleanup();
		return -2;
	}

	DWORD dwBufferLen[10];  
	DWORD dwBufferInLen = 1;  
	DWORD dwBytesReturned = 0;
	iErrorCode=WSAIoctl(SockRaw,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );  
	if(0!=iErrorCode){
		WSACleanup();
		return -3;
	}

	memset(RecvBuf, 0, sizeof(RecvBuf));  
	int nRet;
	CString test,test1;
	while(1){
		nRet = recv(SockRaw, RecvBuf, sizeof(RecvBuf), 0);  
		DecodeIpPack(RecvBuf,nRet);
	}

	return 1;
}


int CSniffer::DecodeIpPack(char *buf, int iBufSize)  
{  
	IP_HEADER *pIpheader;  
	pIpheader = (IP_HEADER *)buf;  
	if(buf[9]!=0x11){
		return -1;
	}
	WORD sPort,dPort;
	WORD udp_len;
	//Check Source IP  
	CString sourceip,destip;
	sourceip.Format("%d.%d.%d.%d",(unsigned char)buf[12],(unsigned char)buf[13],(unsigned char)buf[14],(unsigned char)buf[15]);
	destip.Format("%d.%d.%d.%d",(unsigned char)buf[16],(unsigned char)buf[17],(unsigned char)buf[18],(unsigned char)buf[19]);
	memcpy(&sPort,&buf[20],2);
	memcpy(&dPort,&buf[22],2);
	memcpy(&udp_len,&buf[24],2);
	sPort=ntohs(sPort);
	dPort=ntohs(dPort);
	udp_len=ntohs(udp_len);
	CString tmp,msg,t;
	tmp.Format("%s:%d => %s:%d\nUDP Packet Length:%d\n",sourceip,sPort,destip,dPort,udp_len);
	msg=msg+tmp;
	tmp="";
	for(int i=28;i<iBufSize;i++){
		t.Format("%2.2X ",(unsigned char)buf[i]);
		tmp=tmp+t;
	}
	msg=msg+tmp+"\n";
	tmp="";
	PACK_HEADER *phdr;
	char *pData;
	if(DecodeQQ(&buf[28],iBufSize-28,tmp)>0){
		phdr=new PACK_HEADER;
		pData=new char[tmp.GetLength()+1];
		sprintf(phdr->sIP,"%s",sourceip);
		sprintf(phdr->dIP,"%s",destip);
		phdr->Len=iBufSize-28;
		phdr->sPORT=sPort;
		phdr->dPORT=dPort;
		sprintf(pData,"%s",tmp);
		PostMessage(m_hWnd,MSG_DATAREACH,(WPARAM)phdr,(LPARAM)pData);
	}
	return 1;
}  

int CSniffer::DecodeQQ(char *buf,int buflen,CString &qq_str)
{
	if(buf[buflen-1]!=0x03||buf[0]!=0x02){
		return 0;
	}

	QQ_HEADER qq_hdr;
	int nRet;
	CString tmp;
	GetQQHeader(buf,&qq_hdr);
	switch(qq_hdr.wType){
		case TYPE_GETTOKEN:
			nRet=DecodeGetToken(&buf[7],buflen-8,qq_str,&qq_hdr);
			break;
		case TYPE_LOGIN:
			nRet=DecodeLogin(&buf[7],buflen-8,qq_str,&qq_hdr);
			break; 
		case TYPE_GETFRIENDLIST:
			nRet=DecodeGetFriendList(&buf[7],buflen-8,qq_str,&qq_hdr);
			break;
		case TYPE_GETONLINEFRIENDLIST:
			nRet=DecodeGetOnlineFriendList(&buf[7],buflen-8,qq_str,&qq_hdr);
			break;
		case TYPE_PACKET0X67:
			nRet=Decode0x67(&buf[7],buflen-8,qq_str,&qq_hdr);
			break;
		default:
			nRet=DecodeDefault(&buf[7],buflen-8,qq_str,&qq_hdr);
			break;
	}
	if(qq_hdr.wType==0x67){
		nRet=1;
	}
	else{
		nRet=0;
	}

	if(nRet>0){
		tmp.Format("版本号(0x0001为应答数据):0x%4.4X,帧类型:0x%4.4X,帧序号:0x%4.4X\n",qq_hdr.wVer,qq_hdr.wType,qq_hdr.wIndex);
		qq_str=tmp+qq_str;
		tmp=BufToHex(buf,buflen);
		qq_str=qq_str+CString("原始数据:\n")+tmp;
	}
	return nRet;
}

int CSniffer::GetQQHeader(char *buf,QQ_HEADER *hdr)
{
	hdr->sCode=buf[0];
	memcpy(&hdr->wVer,&buf[1],2);
	hdr->wVer=ntohs(hdr->wVer);
	memcpy(&hdr->wType,&buf[3],2);
	hdr->wType=ntohs(hdr->wType);
	memcpy(&hdr->wIndex,&buf[5],2);
	hdr->wIndex=ntohs(hdr->wIndex);
	if(hdr->sCode!=0x02){
		return 0;
	}
	else{
		return 1;
	}
}

int CSniffer::DecodeGetToken(char *buf,int buflen,CString &qq_str,QQ_HEADER *qq_hdr)
{
	DWORD qq_uid;
	CString str;
	BYTE token_len;
	if(qq_hdr->wVer>=0x00ff){
		if(buflen!=5||buf[4]!=0x00){
			return 0;
		}
		memcpy(&qq_uid,buf,4);
		qq_uid=htonl(qq_uid);
		str.Format("QQ客户端请求登陆令牌,号码:%d\n",qq_uid);
		qq_str=qq_str+str;
	}
	else{
		if(buf[0]!=0x00){
			return 0;
		}
		token_len=buf[1];
		if(token_len!=buflen-2){
			return 0;
		}
		str.Format("获得登录令牌,%d字节:\n%s\n",(unsigned char)token_len,BufToHex(&buf[1],token_len));
		qq_str=qq_str+str;
	}
    return 1;
}

int CSniffer::DecodeLogin(char *buf,int buflen,CString &qq_str,QQ_HEADER *qq_hdr)
{
	char key_rand[16];
	DWORD uid;
	CString str;
	char *decrypted;
	int outlen;
	int nRet;
	char pwdstring[16]; //密码校验串
	char loginmode;//登陆模式
	char logintoken[24];//登陆令牌



	if(qq_hdr->wVer>0x0100){
		if(buflen!=452){
			return 0;
		}
		memcpy(&uid,buf,4);
		memcpy(key_rand,&buf[4],16);
		memcpy(m_key_rand,&buf[4],16);
		uid=ntohl(uid);
		outlen=432;
		decrypted=new char[outlen];
		nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[20],432,(unsigned char *)key_rand,(unsigned char *)decrypted,&outlen);
		if(nRet!=1){
			outlen=432;
			nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[20],432,(unsigned char *)m_pwd_key,(unsigned char *)decrypted,&outlen);
			if(nRet!=1){
				delete decrypted;
				return 0;
			}
		}
		memcpy(pwdstring,decrypted,16);
		loginmode=decrypted[52];
		memcpy(logintoken,&decrypted[70],24);
		str.Format("客户端请求登陆。\nQQ号码:%d,登录模式:0x%2.2X\n随机密钥:\n%s\n密码校验串:\n%s\n登录令牌:\n%s\n解密后字符串:\n%s\n",
			uid,(unsigned char)loginmode,BufToHex(key_rand,16),BufToHex(pwdstring,16),BufToHex(logintoken,24),BufToHex(decrypted,outlen));
		qq_str=str;
		delete decrypted;
		return 1;
	}

	if(buflen==24){ //重定向
		outlen=24;
		decrypted=new char[outlen];
		nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[0],24,(unsigned char *)m_key_rand,(unsigned char *)decrypted,&outlen);
		if(nRet!=1){
			outlen=24;
			nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[0],24,(unsigned char *)m_pwd_key,(unsigned char *)decrypted,&outlen);
			if(nRet!=1){
				delete decrypted;
				return 0;
			}
		}
		if(decrypted[0]!=0x01||outlen!=11){
			delete decrypted;
			return 0;
		}
		WORD port;
		memcpy(&uid,&decrypted[1],4);

		memcpy(&port,&decrypted[9],2);
		port=ntohs(port);
		uid=ntohl(uid);
		
		str.Format("服务器重定向。\nQQ号码:%d\n服务器地址:%d.%d.%d.%d\n端口:%d\n解密后数据:%s\n",
			uid,(unsigned char)decrypted[5],(unsigned char)decrypted[6],(unsigned char)decrypted[7],(unsigned char)decrypted[8],port,BufToHex(decrypted,outlen));
		qq_str=str;
        return 1;
	}
	
	if(buflen==160){
		outlen=160;
		decrypted=new char[outlen];
		nRet=qq_crypt(DECRYPT,(unsigned char *)buf,160,(unsigned char *)m_key_rand,(unsigned char *)decrypted,&outlen);
		if(nRet!=1){
			outlen=160;
			nRet=qq_crypt(DECRYPT,(unsigned char *)buf,160,(unsigned char *)m_pwd_key,(unsigned char *)decrypted,&outlen);
			if(nRet!=1){
				delete decrypted;
				return 0;
			}
		}
		if(decrypted[0]!=0x00){
			delete decrypted;
			return 0;
		}
		
		memcpy(m_key_session,&decrypted[1],16);//绘画密钥
		memcpy(&uid,&decrypted[17],4);
		uid=ntohl(uid);
		unsigned char lastip[4];
		memcpy(m_client_key,&decrypted[79],32);
		memcpy(lastip,&decrypted[123],4);
        
		str.Format("QQ登陆成功。\nQQ号码:%d,上次登陆IP:%d.%d.%d.%d\n会话密钥:\n%s\nClient Key:\n%s\n解密后数据:%s\n",
			uid,lastip[0],lastip[1],lastip[2],lastip[3],BufToHex(m_key_session,16),BufToHex(m_client_key,32),BufToHex(decrypted,outlen));

		qq_str=str;
		delete decrypted;
		return 1;
	}
	



	return 1;
}

int CSniffer::DecodeDefault(char *buf,int buflen,CString &qq_str,QQ_HEADER *qq_hdr)

⌨️ 快捷键说明

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