winpcap编程抓包实例和windump使用

本文发布时间: 2019-Mar-22
WinDump的使用:WinDump.exe version 3.9.5, based on tcpdump version 3.9.5WinPcap version 4.1.3 (packet.dll version 4.1.0.2980), based on libpcap version 1.0 branch 1_0_rel0b (20091008)Usage: WinDump.exe [-aAdDeflLnNOpqRStuUvxX] [ -B size ] [-c count] [ -C file_size ][ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ][ -r file ] [ -s snaplen ] [ -T type ] [ -w file ][ -W filecount ] [ -y datalinktype ] [ -Z user ][ expression ]windump -D列出所有的网卡。windump -h 列出帮助。WinDump.exe -h >mylog.txt 2>&1WinDump.exe -i 4windump -i 2 port 80通过端口80从界面#2记录所有流量windump -i 2 host im-chat.com记录所有从the host im-chat.com.或来或到界面#2的流量windump -i 1 net 127这些参数也可以自由组合。WinDump手册命令格式windump [ -aBdDeflnNOpqRStvxX ] [ -c count ] [ -F file ] [ -i interface ] [ -m module ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -E algo:secret ] [ expression ]描述 Tcpdump 输出网卡数据包中匹配布尔表达式的数据包头。SunOS 系统下使用nit或bpf:要运行tcpdump,你必须有对dev/nit或/dev/bpf*的权利。Solaris系统下使用dlpi:你必须有对 网络假设置的权利。HP-UX系统下使用dlpi:你应该以超级用户ROOT或安装SETUID到ROOT下。IRIX下使用SNOOP:你应该以超级用 户ROOT或安装SETUID到ROOT下。LINUX下:你应该以超级用户ROOT或安装SETUID到ROOT下。在系统Ultrix和Digital UNIX:命令参数-a 将网络和广播地址转化为名称-c 接收指定数据包后退出-d 接收人可读的包匹配编译代码到标准输出,然后停止-dd 以C程序分段方式捕获包匹配代码-ddd 以十进制数据形式捕获包匹配代码-e 在每个捕获行打印链路层头标-E algo:secret为解密IPSE ESP包使用算法。算法可以是des-cbc, 3des-cbc, blowfish-cbc, rc3-cbc, cast128-cbc, 或none。默认值是desc-cbc。只有当TCPDUMP编译时使用激活加密选项时,才可以解密数据包。Secret是ESP密匙是ASCII码。当前还不能认为一定是二进制值。该选项是以RFC2406ESP为假设,而不是RFC1827 ESP。只用于调试,不鼓励用真正的密码作为选项。当你在PS或其他场合,把IPSEC密码写在命令行上时,会被他人看到。-f 不用符号而用数字方式输出外部英特网地址 -F 使用文件作为过滤表达式的输入。命令行的其他部分会被忽略。-i 在接口上监听。如果没有指定,TCPDUMP将搜索系统接口列表中最小,被配置激活的接口(LOOPBACK接口除外)。可用最先匹配替换这种关系。在 WINDOWS中接口可以是网卡的名称,或是网卡的号码(-D参数可显示该号码)。内核为2。2或其后的LINUX系统,参数“ANY”可以获取所有接口 的数据。应注意的是在混乱模式下不能使用“ANY”参数。-l 标准输出行缓存。如果你想在捕获数据时查看的话,这个参数很有用。例如:“tcpdump -l │ tee dat” or “tcpdump -l > dat & tail -f dat”.” n 不要将地址(如主机地址,端口号)转换为名称 -N 不要打印主机名称的域名限定。如:如果你使用该参数,TCPDUMP会输出“NIC”而不是“NIC。DDN。MIL”。-m 从文件模块中载入SMI MIB 模块定义。这个选项可以为TCPDUMP载入多个MIB模块-O 不要运行包匹配代码优化器。只有在你怀疑优化器有问题时可以使用这个参数。-p 不要让接口处于“混乱”模式。注意接口可能由于其他原因处于“混乱”模式;因此“-p”不能用作以太网络主机或广播的缩写。-q 快速(安静?)输出。打印较少的协议信息,因此输出行更短。-r 从文件中读取包(与参数据-W一起使用)。如果文件是“-”就使用标准输入。-s 不使用默认的68个字节,更改从每个包中获取数据的字节数量( SunOS系统实际最小为96)。对于IP,ICMP,TCP和UDP包68个字节已足够,但是对命名服务和NFS包,他们的协议会被截断(见下面)。包 被截断是因为在使用参数“[│proto]”输出时指定受限制的快照,proto是被截断协议层的名称。注意如果使用大的快照会增加处理包的时间,并且明 显地减少包的缓存数量。也许会导致包的丢失。你应该将snaplen 设置成你感兴趣协议的最小数。当snaplen 为0时接收整个包。-T 根据表达式将选中的数据包表达成指定的类型。当前已有的类型有CNFP(Cisco的网络流量协议),rpc(远端程序调用),rtp(实时程序协议), rtcp(实时程序控制协议),snmp(简单网络管理协议),vat(可视单频工具),和wb(分布式白板)。 -R 假设ESP/AH包遵守旧的说明(RFC1825到RFC1829)。如果该参数被指定,TCPDUMP不打输出域。因为在ESP/AH说明中没有协议版 本,TCPDUMP就无法推断出其版本号。 -S 输出绝对TCP序列号,而不是相对号。-t 每个捕获行不要显示时间戳。 -tt 每个捕获行显示非格式化的时间时间戳。-v 详细输出。例如,显示生存时间TTL,标识符,总长度和IP数据包的选项。也进行额外的包完整性较验,如验证IP和ICMP的头标较验值。-vv 更为详细的输出。例如,显示NFS中继包中的其他域。-vvv 很详细的输出。如,完全输出TELNET SB… SE选项。带-X参数的TELNET,打印并以十六进制输出。-w 不对原始数据包解析打印而是转到文件中去。以后可用-r选项打印。当文件名为“-”表示标准输出。 -x 以十六进制(去除链路层头标)输出每个数据包。输出整个包的小部分或snaplen 个字节。-X 输出十六进制同时,输出ASCII码。如果-x也被设置,数据包会以十六制/ASCII码显示。这对于分析新协议非常方便。如果-x也没有设置,一些数据包的部分会以十六制/ASCII码显示。 Win32特殊扩展-B 以千字节为单位设置驱动缓存。默认缓存为1M(即1000)。如果在获取数据包时有数据丢失,建议使用该参数增大核心缓存大小,因为驱动缓存大小对数据捕获性能有很大影响。-D 显示系统上可用的网卡列表。该参数将返回每块网卡的号码,名称和描述。下载:http://www.winpcap.org/archive/4.1beta5_WpdPack.zip这个包里面有很多例子,下面我们就可以编程实现了:#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>#define HAVE_REMOTE#include <pcap.h>#include <iomanip>#include <string>#include <stdio.h>using namespace std;#include <pcap.h>#pragma comment(lib,"wpcap.lib") #pragma comment(lib,"ws2_32.lib") //https://github.com/yfnick/winpcap/blob/master/ref_http/main.cpp//demo https://github.com/yfnick/winpcap/*Ethernet Heder*/struct ether_header{u_int8_t ether_dhost[6]; /* destination eth addr */u_int8_t ether_shost[6]; /* source ether addr */u_int16_t ether_type; /* packet type ID field */};/* 4 bytes IP address */struct ip_address{u_char byte1;u_char byte2;u_char byte3;u_char byte4;};/* IPv4 header */struct ip_header{u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)u_char tos; // Type of serviceu_short tlen; // Total lengthu_short identification; // Identificationu_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)u_char ttl; // Time to liveu_char proto; // Protocolu_short crc; // Header checksumip_address saddr; // Source addressip_address daddr; // Destination addressu_int op_pad; // Option + Padding};/* UDP header*/struct udp_header{u_short sport; // Source portu_short dport; // Destination portu_short len; // Datagram lengthu_short crc; // Checksum};/*TCP Header*/struct tcp_header{u_int16_t th_sport; /* source port */u_int16_t th_dport; /* destination port */u_int32_t th_seq; /* sequence number */u_int32_t th_ack; /* acknowledgement number */u_int16_t th_len_resv_code; // Datagram length and reserved codeu_int16_t th_win; /* window */u_int16_t th_sum; /* checksum */u_int16_t th_urp; /* urgent pointer */};int main(){//retrieve the devices listpcap_if_t *all_devs;char err_buff[PCAP_ERRBUF_SIZE];if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &all_devs, err_buff) == -1){cerr << "Error in pcap_findalldevs_ex " << err_buff << endl;return -1;}//get the device index,default is the first oneint dev_idx = 2;pcap_if_t *dev = all_devs;for (int i = 0; i < dev_idx; ++i, dev = dev->next);//jump to the device of the specified indexcout << "Listen on: " << dev->name << endl;cout << "****************************************" << endl;//get the netcard adapterpcap_t *adpt_hdl = pcap_open(dev->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, err_buff);if (adpt_hdl == NULL){cerr << "Unable to open adapter " << dev->name << endl;pcap_freealldevs(all_devs);return -1;}/* At this point, we don't need any more the device list. Free it */pcap_freealldevs(all_devs);//analyze each packetstruct pcap_pkthdr *header;const u_char *pkt_data;int rst = 0;char x;FILE *fp, *fq;fp = fopen("http.txt", "w+");fq = fopen("ac.txt", "w+");while ((rst = pcap_next_ex(adpt_hdl, &header, &pkt_data)) >= 0){if (rst == 0){//time out and not packet capturedcontinue;}ether_header *eh = (ether_header*)pkt_data;if (ntohs(eh->ether_type) == 0x0800){ // ip packet onlyip_header *ih = (ip_header*)(pkt_data + 14);if (ntohs(ih->proto) == 0x0600){ // tcp packet onlyint ip_len = ntohs(ih->tlen);//ip_len = ip_body + ip_headerbool find_http = false;string http_txt = "";//char* http;char* ip_pkt_data = (char*)ih;for (int i = 0; i < ip_len; ++i){//check the http requestif (!find_http && ( 3 < ip_len && strncmp(ip_pkt_data + i, "GET", strlen("GET")) == 0)|| (i + 4 < ip_len && strncmp(ip_pkt_data + i, "POST", strlen("POST")) == 0)){find_http = true;}//check the http responseif (!find_http && i + 8 < ip_len && strncmp(ip_pkt_data + i, "HTTP/1.1", strlen("HTTP/1.1")) == 0){find_http = true;}//collect the http textif (find_http){http_txt += ip_pkt_data[i];fputc(ip_pkt_data[i], fp);if ((ip_pkt_data[i] > 'A'&&ip_pkt_data[i]<'Z') || (ip_pkt_data[i]>'a'&&ip_pkt_data[i]<'z')){if ((ip_pkt_data[i]>'A'&&ip_pkt_data[i] < 'Z'))x = ip_pkt_data[i] - 'A' + 'a';else x = ip_pkt_data[i];fputc(x, fq);}}}//print the http request or responseif (http_txt != ""){cout << http_txt;cout << endl << "***********************************************************" << endl << endl;}}}}return 0;}#define HAVE_REMOTE#define _CRT_SECURE_NO_WARNINGS 1#include <pcap.h>#pragma comment(lib,"wpcap.lib") /* 回调函数原型 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);int main(int argc, char **argv){pcap_if_t *alldevs;pcap_if_t *d;int inum;int i = 0;pcap_t *adhandle;char errbuf[PCAP_ERRBUF_SIZE];pcap_dumper_t *dumpfile;/* 检查程序输入参数 */if (argc != 2){printf("usage: %s filename", argv[0]);return -1;}/* 获取本机设备列表 */if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1){fprintf(stderr, "Error in pcap_findalldevs: %s", errbuf);exit(1);}/* 打印列表 */for (d = alldevs; d; d = d->next){printf("%d. %s", ++i, d->name);if (d->description)printf(" (%s)", d->description);elseprintf(" (No description available)");}if (i == 0){printf("No interfaces found! Make sure WinPcap is installed.");return -1;}printf("Enter the interface number (1-%d):", i);scanf("%d", &inum);if (inum < 1 || inum > i){printf("Interface number out of range.");/* 释放列表 */pcap_freealldevs(alldevs);return -1;}/* 跳转到选中的适配器 */for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);/* 打开适配器 */if ((adhandle = pcap_open(d->name, // 设备名65536, // 要捕捉的数据包的部分// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式1000, // 读取超时时间NULL, // 远程机器验证errbuf // 错误缓冲池)) == NULL){fprintf(stderr, "Unable to open the adapter. %s is not supported by WinPcap", d->name);/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;}/* 打开堆文件 */dumpfile = pcap_dump_open(adhandle, argv[1]);if (dumpfile == NULL){fprintf(stderr, "Error opening output file");return -1;}printf("listening on %s... Press Ctrl+C to stop...", d->description);/* 释放设备列表 */pcap_freealldevs(alldevs);/* 开始捕获 */pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);return 0;}/* 回调函数,用来处理数据包 */void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data){/* 保存数据包到堆文件 */pcap_dump(dumpfile, header, pkt_data);}


(以上内容不代表本站观点。)
---------------------------------
本网站以及域名有仲裁协议。
本網站以及域名有仲裁協議。

2024-Mar-04 02:08pm
栏目列表