分享
分销 收藏 举报 申诉 / 7
播放页_导航下方通栏广告

类型手把手教你捕获数据包.doc

  • 上传人:仙人****88
  • 文档编号:6254987
  • 上传时间:2024-12-03
  • 格式:DOC
  • 页数:7
  • 大小:61.50KB
  • 下载积分:10 金币
  • 播放页_非在线预览资源立即下载上方广告
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    手把手 捕获 数据包
    资源描述:
    手把手教你捕获数据包 【导读】在通常情况下,网络通信的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取与自己无关的的数据包。 一.捕获数据包的实现原理: 在通常情况下,网络通信的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取与自己无关的的数据包。 所以我们要想实现截获流经网络设备的所有数据包,就要采取一点特别的手段了: 将网卡设置为混杂模式。 这样一来,该主机的网卡就可以捕获到所有流经其网卡的数据包和帧。 但是要注意一点,这种截获仅仅是数据包的一份拷贝,而不能对其进行截断,要想截断网络流量就要采用一些更底层的办法了,不在本文的讨论范围之内。   二. 捕获数据包的编程实现: 1.raw socket的实现方法 不同于我们常用的数据流套接字和数据报套接字,在创建了原始套接字后,需要用WSAIoctl()函数来设置一下,它的定义是这样的 int WSAIoctl(   SOCKET s,   DWORD dwIoControlCode,   LPVOID lpvInBuffer,   DWORD cbInBuffer,   LPVOID lpvOutBuffer,   DWORD cbOutBuffer,   LPDWORD lpcbBytesReturned,   LPWSAOVERLAPPED lpOverlapped,   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); 虽然咋一看参数比较多,但是其实我们最关心的只是其中的第二项而已,我们需要做的就是把第二项设置为SIO_RCVALL,讲了这么多其实要做的就是这么一行代码,很简单吧?^_^  当然我们还可以指定是否亲自处理IP头,但是这并不是必须的。 完整的代码类似与如下这样,加粗的代码是与平常不同的需要注意的地方: ( 为了让代码一目了然,我把错误处理去掉了,下同) #include “WinSock2.h” #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)   SOCKET SnifferSocket   WSADATA wsaData;   iFlag=WSAStartup(MAKEWORD(2,2),&wsaData);           //开启winsock.dll                                   SnifferSocket=WSASocket(AF_INET,             //创建raw  socket SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);     char FAR name[128];                                //获取本机IP地址 gethostname(name, sizeof(name));   struct hostent FAR * pHostent;   pHostent = gethostbyname(name);     SOCKADDR_IN sa;                           //填充SOCKADDR_IN结构的内容   sa.sin_family = AF_INET;   sa.sin_port = htons(6000);           // 端口号可以随便改,当然与当然系统不能冲突   memcpy(&(sa.sin_addr),pHostent->h_addr,pHostent->h_length);   bind(SnifferSocket,(LPSOCKADDR)&sa,sizeof(sa));            //绑定   // 置ioctl来接收所有网络数据,关键步骤   DWORD dwBufferLen[10] ;   DWORD dwBufferInLen = 1 ;   DWORD dwBytesReturned = 0 ;   WSAIoctl(SnifferSocket, IO_RCVALL,&dwBufferInLen, izeof(dwBufferInLen),   &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL ); 至此,实际就可以开始对网络数据包进行嗅探了,而对于数据包的接收还是和普通的socket一样,通过recv()函数来完成,因为这里涉及到不同的socket模型,接收方法差别很大,所以在此就不提供接收的代码了。   2.winpcap的实现方法:----------------------------------------------------------------------- winpcap驱动包,是我们玩转数据包不可或缺的好东东,winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据报,主要为我们提供了四大功能: 功能: 1> 捕获原始数据报,包括在共享网络上各主机发送/接收的以及相互之间交换的数据报; 2> 在数据报发往应用程序之前,按照自定义的规则将某些特殊的数据报过滤掉; 3> 在网络上发送原始的数据报; 4> 收集网络通信过程中的统计信息 如果环境允许的话(比如你做的不是木马程序),我还是推荐大家用winpcap来截获数据包,因为它的功能更强大,工作效率更高,唯一的缺点就是在运行用winpcap开发的程序以前,都要在主机上先安装winpcap的driver。 而且一会我们就会发现它比raw socket功能强大的多,而且工作得更为底层,最明显的理由就是raw socket捕获的数据包是没有以太头的,此乃后话。 至于怎么来安装使用,请参考本系列的系列一《手把手教你玩转ARP包中的》,里面有详细的加载winpcap驱动的方法^_^ 废话不多说了,让我们转入正题, 具体用winpcap来截获数据包需要做如下的一些工作: A . 枚举本机网卡的信息(主要是获得网卡的名称)    其中要用到pcap_findalldevs函数,它是这样定义的    /************************************************* int pcap_findalldevs  (  pcap_if_t **    alldevsp,                               char *    errbuf                           )  功能:         枚举系统所有网络设备的信息 参数:  alldevsp:  是一个pcap_if_t结构体的指针, 如果函数pcap_findalldevs函数执行成功, 将获得一个可用网卡的列表,而里面存储的就是第一个元素的指针。              Errbuf:    存储错误信息的字符串      返回值: int :   如果返回0 则执行成功,错误返回 -1。   ************************************************/    我们利用这个函数来获得网卡名字的完整代码如下:          pcap_if_t* alldevs;        pcap_if_t* d;        char errbuf[PCAP_ERRBUF_SIZE];        pcap_findalldevs(&alldevs,errbuf);  // 获得网络设备指针        for(d=alldevs;d;d=d->next)          // 枚举网卡然后添加到ComboBox中        { d->name; //d->name就是我们需要的网卡名字字符串,按照你自己的需要保存到你的相应变量中去        } pcap_freealldevs(alldevs);             // 释放alldev资源 B. 打开相应网卡并设置为混杂模式:    在此之前肯定要有一段让用户选择网卡、并获得用户选择的网卡的名字的代码,既然上面已经可以获得所有网卡的名字了,这段代码就暂且略过了。    我们主要是要用到 pcap_open_live 函数,不过这个函数winpcap的开发小组已经建议用pcap_open 函数来代替,不过因为我的代码里面用的就是pcap_open_live,所以也不便于修改了,不过pcap_open_live使用起来也是没有任何问题的,下面是pcap_open_live的函数声明: /************************************************* pcap_t* pcap_open_live  (  char *    device,                               int    snaplen,    int    promisc,    int    to_ms,    char *    ebuf  )        功能:            根据网卡名字打开网卡,并设置为混杂模式,然后返回其句柄      参数:            Device  : 就是前前面我们获得的网卡的名字;            Snaplen :  我们从每个数据包里取得数据的长度,比如设置为100,则每次我们只是获得每个数据包 100 个长度的数据,没有什么特殊需求的话就把它设置为65535最大值就可以了;            Promisc:这个参数就是设置是否把网卡设置为“混杂模式”,设置为 1 即可;            to_ms :   超时时间,毫秒,一般设置为 1000即可。      返回值:            pcap_t :  类似于一个网卡“句柄”之类的,不过当然不是,这个参数是后面截获数据要用到的。 虽然看起来比较复杂,不过用起来还是非常简单的,其实 1 行就OK了:     pcap_t* adhandle;        char errbuf[PCAP_ERRBUF_SIZE]; // 打开网卡,并且设置为混杂模式 // pCardName是前面传来的网卡名字参数 adhandle = pcap_open_live(pCardName,65535,1,1000,errbuf);   C. 截获数据包并保存为文件:------------------------------------------------------      当然,不把数据包保存为文件也可以,不过如果不保存的话,只能在截获到数据包的那一瞬间进行分析,转眼就没了^_^ 所以,为了便于日后分析,所以高手以及我个人经常是把数据包保存下来的慢慢分析的。 但是注意网络流量,在流量非常大的时候注意硬盘空间呵呵,常常几秒中就有好几兆是很正常的事情。 下面首先来详细讲解一下,这个步骤中需要用到的winpcap函数: /************************************************************** pcap_dumper_t* pcap_dump_open  (  pcap_t *    p,                                        const char *    fname  ) 功能:       建立或者打开存储数据包内容的文件,并返回其句柄 参数:        pcap_t *    p     :前面打开的网卡句柄;       const char * fname :要保存的文件名字    返回值:        pcap_dumper_t* : 保存文件的描述句柄,具体细节我们不用关心 ***************************************************************/ /*************************************************************** int pcap_next_ex          (  pcap_t *    p,                                struct pcap_pkthdr **    pkt_header,    u_char **    pkt_data  )   功能:       从网卡或者数据包文件中读取数据内容 参数:       pcap_t *    p:    网卡句柄       struct pcap_pkthdr ** pkt_header: 并非是数据包的指针, 只是与数据包捕获驱动有关的一个Header       u_char ** pkt_data:指向数据包内容的指针 ,包括了协议头   返回值:           1 : 如果成功读取数据包           0 :pcap_open_live()设定的超时时间之内没有读取到内容           -1: 出现错误           -2: 读文件时读到了末尾 ***************************************************************/ /*************************************************************** void pcap_dump  (  u_char *    user,                         const struct pcap_pkthdr *    h,    const u_char *    sp  )    功能:       将数据包内容依次写入pcap_dump_open()指定的文件中 参数:       u_char * user   :  网卡句柄       const struct pcap_pkthdr * h: 并非是数据包的指针, 只是与数据包捕获驱动有关的一个Header       const u_char * sp: 数据包内容指针     返回值:           Void ****************************************************************/ 下面给出一段完整的捕获数据包的代码,是在线程中写的,为了程序清晰,我去掉了错误处理代码以及线程退出的代码,完整代码可下载文后的示例源码,老规矩,重要的步骤用粗体字标出。 我们实际在捕获数据包的时候也最好是把代码放到另外的线程中。 /********************************************************* *   进程: *                   这个是程序的核心部分,完成数据包的截获 *     参数: *                   pParam: 用户选择的用来捕获数据的网卡的名字 *********************************************************/ UINT CaptureThread(LPVOID pParam) {      const char* pCardName=(char*)pParam; // 转换参数,获得网卡名字        pcap_t* adhandle;        char errbuf[PCAP_ERRBUF_SIZE];                     // 打开网卡,并且设置为混杂模式  adhandle=pcap_open_live(pCardName,65535,1,1000,errbuf);    {          pcap_dumper_t* dumpfile; // 建立存储截获数据包的文件        dumpfile=pcap_dump_open(adhandle, "Packet.dat");             int re;        pcap_pkthdr* header;      // Header        u_char* pkt_data;         // 数据包内容指针 // 从网卡或者文件中不停读取数据包信息 while((re=pcap_next_ex (adhandle,&header,(const u_char**)&pkt_data))>=0)       {           // 将捕获的数据包存入文件          pcap_dump((unsigned char*)dumpfile,header,pkt_data);             }        return 0; }  将个线程加入到程序里面启动以后。。。等等,如何来启动这个线程就不用我说了吧,类似这样的代码就可以 ::AfxBeginThread(CaptureThread,chNIC);     // chNIC是网卡的名字,char* 类型 启动线程一段时间以后(几秒中就有效果了),可以看到数据包已经被成功的截获下来,并存储到程序目录下的Packet.dat文件中。 ===================================================== 至此,数据包的截获方法就讲完了,大家看了这篇文章,其实你就一定也明白了,无论是raw socket的方法还是winpcap的方法,其实都很简单的,真的没有什么东西,只是会让不明白原理的人看起来很神秘而已,isn’t it? 呵呵,不过也不要高兴的太早,这个保存下来的数据包文件,你可以试着用UltraEdit打开这个文件看看,是不是大部分都是乱码?基本上没有什么可读性,这是因为: 此时捕获到的数据包并不仅仅是单纯的数据信息,而是包含有 IP头、 TCP头等信息头的最原始的数据信息,这些信息保留了它在网络传输时的原貌。通过对这些在低层传输的原始信息的分析可以得到有关网络的一些信息。由于这些数据经过了网络层和传输层的打包,因此需要根据其附加的帧头对数据包进行分析。 呵呵,所以我们要走的路还很长,这只是刚刚入门而已^_^
    展开阅读全文
    提示  咨信网温馨提示:
    1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
    2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
    3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
    4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
    5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
    6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

    开通VIP折扣优惠下载文档

    自信AI创作助手
    关于本文
    本文标题:手把手教你捕获数据包.doc
    链接地址:https://www.zixin.com.cn/doc/6254987.html
    页脚通栏广告

    Copyright ©2010-2026   All Rights Reserved  宁波自信网络信息技术有限公司 版权所有   |  客服电话:0574-28810668    微信客服:咨信网客服    投诉电话:18658249818   

    违法和不良信息举报邮箱:help@zixin.com.cn    文档合作和网站合作邮箱:fuwu@zixin.com.cn    意见反馈和侵权处理邮箱:1219186828@qq.com   | 证照中心

    12321jubao.png12321网络举报中心 电话:010-12321  jubao.png中国互联网举报中心 电话:12377   gongan.png浙公网安备33021202000488号  icp.png浙ICP备2021020529号-1 浙B2-20240490   


    关注我们 :微信公众号  抖音  微博  LOFTER               

    自信网络  |  ZixinNetwork