<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-17  評(píng)論-64  文章-79  trackbacks-1

    ??

    ?? ?? 經(jīng)常看到論壇有人問(wèn)起關(guān)于數(shù)據(jù)包的截獲、分析等問(wèn)題,幸好本人也對(duì)此略有所知,也寫(xiě)過(guò)很多的 sniffer ,所以就想寫(xiě)一系列的文章來(lái)詳細(xì)深入的探討關(guān)于數(shù)據(jù)包的知識(shí)。

    我希望通過(guò)這一系列的文章,能使得關(guān)于數(shù)據(jù)包的知識(shí)得以普及,所以這系列的每一篇文章我都會(huì)有由淺入深的解釋、詳細(xì)的分析、以及編碼步驟,另外附上帶有詳細(xì)注釋的源碼 ( 為了照顧大多數(shù)朋友,我提供的都是 MFC 的源碼 )

    不過(guò)由于也是初學(xué)者,疏漏之處還望不吝指正。

    本文凝聚著筆者心血,如要轉(zhuǎn)載,請(qǐng)指明原作者及出處,謝謝! ^_^

    ?

    OK,. Let’s go !? Have fun ! ! q^_^p

    ?

    第二篇 ?? 手把手教你捕獲數(shù)據(jù)包

    目錄:

    一. 捕獲數(shù)據(jù)包的實(shí)現(xiàn)原理

    二. 捕獲數(shù)據(jù)包的編程實(shí)現(xiàn):

    1.? ?raw socket 的實(shí)現(xiàn)方法

    2.? ?Winpcap 的實(shí)現(xiàn)方法

    a.????? 枚舉本機(jī)網(wǎng)卡的信息

    b.????? 打開(kāi)相應(yīng)網(wǎng)卡并設(shè)置為混雜模式

    c.?????? 截獲數(shù)據(jù)包并保存為文件

    ?

    作者:

    CSDN? VC/MFC 網(wǎng)絡(luò)編程版主 PiggyXP?

    ?

    一.捕獲數(shù)據(jù)包的實(shí)現(xiàn)原理: --------------------------------------------------------------------

    在通常情況下,網(wǎng)絡(luò)通信的套接字程序只能響應(yīng)與自己硬件地址相匹配的或是以廣播形式發(fā)出的數(shù)據(jù)幀,對(duì)于其他形式的數(shù)據(jù)幀比如已到達(dá)網(wǎng)絡(luò)接口但卻不是發(fā)給此地址的數(shù)據(jù)幀,網(wǎng)絡(luò)接口在驗(yàn)證投遞地址并非自身地址之后將不引起響應(yīng),也就是說(shuō)應(yīng)用程序無(wú)法收取與自己無(wú)關(guān)的的數(shù)據(jù)包。

    所以我們要想實(shí)現(xiàn)截獲流經(jīng)網(wǎng)絡(luò)設(shè)備的所有數(shù)據(jù)包,就要采取一點(diǎn)特別的手段了:

    將網(wǎng)卡設(shè)置為混雜模式。

    這樣一來(lái),該主機(jī)的網(wǎng)卡就可以捕獲到所有流經(jīng)其網(wǎng)卡的數(shù)據(jù)包和幀。

    但是要注意一點(diǎn),這種截獲僅僅是數(shù)據(jù)包的一份拷貝,而不能對(duì)其進(jìn)行截?cái)?,要想截?cái)嗑W(wǎng)絡(luò)流量就要采用一些更底層的辦法了,不在本文的討論范圍之內(nèi)。

    ?

    二. 捕獲數(shù)據(jù)包的編程實(shí)現(xiàn):

    1.raw socket 的實(shí)現(xiàn)方法 --------------------------------------------------------------------

    不同于我們常用的數(shù)據(jù)流套接字和數(shù)據(jù)報(bào)套接字,在創(chuàng)建了原始套接字后,需要用 WSAIoctl() 函數(shù)來(lái)設(shè)置一下,它的定義是這樣的

    int WSAIoctl(

    ? SOCKET s,

    ? DWORD dwIoControlCode,

    ? LPVOID lpvInBuffer,

    ? DWORD cbInBuffer,

    ? LPVOID lpvOutBuffer,

    ? DWORD cbOutBuffer,

    ? LPDWORD lpcbBytesReturned,

    ? LPWSAOVERLAPPED lpOverlapped,

    ? LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

    );

    雖然咋一看參數(shù)比較多,但是其實(shí)我們最關(guān)心的只是其中的第二項(xiàng)而已,我們需要做的就是把第二項(xiàng)設(shè)置為 SIO_RCVALL ,講了這么多其實(shí)要做的就是這么一行代碼,很簡(jiǎn)單吧? ^_^

    ? 當(dāng)然我們還可以指定是否親自處理 IP 頭,但是這并不是必須的。

    完整的代碼類(lèi)似與如下這樣,加粗的代碼是與平常不同的需要注意的地方:

    ( 為了讓代碼一目了然,我把錯(cuò)誤處理去掉了,下同 )

    ?

    #include “WinSock2.h”

    #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

    ?

    SOCKET SnifferSocket

    ? WSADATA wsaData;

    ? iFlag=WSAStartup(MAKEWORD(2,2),&wsaData);???????? ? // 開(kāi)啟 winsock.dll

    ?????????????????????????????????

    SnifferSocket=WSASocket(AF_INET, ????????????// 創(chuàng)建 raw? socket

    SOCK_RAW, IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

    ?

    ? char FAR name[128];???? ???????????????????????????// 獲取本機(jī) IP 地址

    gethostname(name, sizeof(name));

    ? struct hostent FAR * pHostent;

    ? pHostent = gethostbyname(name);

    ?

    ? SOCKADDR_IN sa;?????????????????????????? // 填充 SOCKADDR_IN 結(jié)構(gòu)的內(nèi)容

    ? sa.sin_family = AF_INET;

    ? sa.sin_port = htons(6000);????????? ?// 端口號(hào)可以隨便改,當(dāng)然與當(dāng)然系統(tǒng)不能沖突

    ? memcpy(&(sa.sin_addr),pHostent->h_addr,pHostent->h_length);

    ?

    bind(SnifferSocket,(LPSOCKADDR)&sa,sizeof(sa));????? ????? // 綁定

    ?

    ? // ioctl 來(lái)接收所有網(wǎng)絡(luò)數(shù)據(jù) , 關(guān)鍵步驟

    ? DWORD dwBufferLen[10] ;

    ? DWORD dwBufferInLen = 1 ;

    ? DWORD dwBytesReturned = 0 ;

    ? WSAIoctl(SnifferSocket, IO_RCVALL,&dwBufferInLen, izeof(dwBufferInLen),

    ??????? &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );

    ?

    至此,實(shí)際就可以開(kāi)始對(duì)網(wǎng)絡(luò)數(shù)據(jù)包進(jìn)行嗅探了,而對(duì)于數(shù)據(jù)包的接收還是和普通的 socket 一樣,通過(guò) recv() 函數(shù)來(lái)完成,因?yàn)檫@里涉及到不同的 socket 模型,接收方法差別很大,所以在此就不提供接收的代碼了。

    ?

    2.winpcap 的實(shí)現(xiàn)方法: -----------------------------------------------------------------------

    winpcap 驅(qū)動(dòng)包,是我們玩轉(zhuǎn)數(shù)據(jù)包不可或缺的好東東, winpcap 的主要功能在于獨(dú)立于主機(jī)協(xié)議(如 TCP-IP) 而發(fā)送和接收原始數(shù)據(jù)報(bào),主要為我們提供了四大功能:

    功能:
    ??? 1>
    捕獲原始數(shù)據(jù)報(bào),包括在共享網(wǎng)絡(luò)上各主機(jī)發(fā)送 / 接收的以及相互之間交換的數(shù)據(jù)報(bào);
    ??? 2>
    在數(shù)據(jù)報(bào)發(fā)往應(yīng)用程序之前,按照自定義的規(guī)則將某些特殊的數(shù)據(jù)報(bào)過(guò)濾掉;
    ??? 3>
    在網(wǎng)絡(luò)上發(fā)送原始的數(shù)據(jù)報(bào);
    ??? 4>
    收集網(wǎng)絡(luò)通信過(guò)程中的統(tǒng)計(jì)信息

    如果環(huán)境允許的話 ( 比如你做的不是木馬程序 ) ,我還是推薦大家用 winpcap 來(lái)截獲數(shù)據(jù)包,因?yàn)樗墓δ芨鼜?qiáng)大,工作效率更高,唯一的缺點(diǎn)就是在運(yùn)行用 winpcap 開(kāi)發(fā)的程序以前,都要在主機(jī)上先安裝 winpcap driver

    而且一會(huì)我們就會(huì)發(fā)現(xiàn)它比 raw socket 功能強(qiáng)大的多,而且工作得更為底層,最明顯的理由就是 raw socket 捕獲的數(shù)據(jù)包是沒(méi)有以太頭的,此乃后話。

    至于怎么來(lái)安裝使用,請(qǐng)參考本系列的系列一《手把手教你玩轉(zhuǎn) ARP 包中的》,里面有詳細(xì)的加載 winpcap 驅(qū)動(dòng)的方法 ^_^

    廢話不多說(shuō)了,讓我們轉(zhuǎn)入正題 , 具體用 winpcap 來(lái)截獲數(shù)據(jù)包需要做如下的一些工作:

    A . 枚舉本機(jī)網(wǎng)卡的信息 ( 主要是獲得網(wǎng)卡的名稱(chēng) )

    ?? 其中要用到 pcap_findalldevs 函數(shù),它是這樣定義的

    ?? /*************************************************

    int pcap_findalldevs? (? pcap_if_t **??? alldevsp,?

    ? ??????????????????????? ??? ?char *??? errbuf

    ? ? ????????????????? ??? ???)?

    ?? ?? 功能:

    ??????????? ? 枚舉系統(tǒng)所有網(wǎng)絡(luò)設(shè)備的信息

    ???? 參數(shù): ? alldevsp ? 是一個(gè) pcap_if_t 結(jié)構(gòu)體的指針,如果函數(shù) pcap_findalldevs 函數(shù)執(zhí)行成功,將獲得一個(gè)可用網(wǎng)卡的列表,而里面存儲(chǔ)的就是第一個(gè)元素的指針。

    ????????? ?? ?Errbuf ??? 存儲(chǔ)錯(cuò)誤信息的字符串

    ???? 返回值: int ?? 如果返回 0 則執(zhí)行成功,錯(cuò)誤返回 -1

    ? ? *************************************************/

    ?? 我們利用這個(gè)函數(shù)來(lái)獲得網(wǎng)卡名字的完整代碼如下:

    ?

    ?????? pcap_if_t* alldevs;

    ?????? pcap_if_t* d;

    ?????? char errbuf[PCAP_ERRBUF_SIZE];

    ?????? pcap_findalldevs(&alldevs,errbuf);?????? // 獲得網(wǎng)絡(luò)設(shè)備指針

    ?????? for(d=alldevs;d;d=d->next)?????????????? // 枚舉網(wǎng)卡然后添加到 ComboBox

    ?????? {

    d->name;?????????????????????????? ?// d->name 就是我們需要的網(wǎng)卡名字字符串,按照你 // 自己的需要保存到你的相應(yīng)變量中去

    ?????? }

    pcap_freealldevs(alldevs);?????????????? // 釋放 alldev 資源

    posted on 2007-02-16 15:51 飛鳥(niǎo) 閱讀(633) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): VC
    主站蜘蛛池模板: 91在线亚洲综合在线| 亚洲美女精品视频| 久久亚洲精品成人综合| 亚洲国产天堂在线观看| 亚洲国产成人精品无码区在线网站 | 国产片免费福利片永久| 亚洲天堂在线视频| 亚洲国产老鸭窝一区二区三区| 亚洲三级在线免费观看| 日韩成人精品日本亚洲| 国产成人免费AV在线播放| 日韩欧毛片免费视频| 亚洲男人的天堂一区二区| 亚洲男人第一av网站| 亚洲一区二区观看播放| 亚洲第一视频在线观看免费| 4399影视免费观看高清直播| 国产青草视频免费观看97 | 红杏亚洲影院一区二区三区| 亚洲视频一区网站| 老子影院午夜伦不卡亚洲| 免费日本一区二区| 在线播放免费播放av片| 亚洲AV无码不卡在线播放| 亚洲一本一道一区二区三区| 好吊色永久免费视频大全| 无码国产精品一区二区免费 | 日韩免费无码一区二区三区 | 在线精品免费视频| 亚洲AV无码不卡无码| 女bbbbxxxx另类亚洲| 99视频精品全部免费观看| 亚洲精品NV久久久久久久久久| 久久精品国产亚洲av日韩| 边摸边吃奶边做爽免费视频网站| 3344永久在线观看视频免费首页 | 亚洲爆乳大丰满无码专区| 日韩免费在线观看视频| 国产一区二区免费在线| 91大神亚洲影视在线| 曰韩无码AV片免费播放不卡 |