1. 程式人生 > >分析802.11無線報文hexdump內容:利用wireshark自帶二進位制工具text2pcap將hexdump內容轉換為pcap檔案

分析802.11無線報文hexdump內容:利用wireshark自帶二進位制工具text2pcap將hexdump內容轉換為pcap檔案

除錯wifi驅動,有時會將報文內容以16進位制形式打印出來,如下是一個beacon報文的內容:

0000 80 00 00 00 ff ff ff ff ff ff 40 e3 d6 cb fe d0
0010 40 e3 d6 cb fe d0 70 29 7b 00 55 41 00 00 00 00
0020 64 00 11 01 00 06 50 61 72 72 6f 74 01 06 98 a4
0030 30 48 60 6c 03 01 95 05 04 00 01 00 00 20 01 00
0040 23 02 1b 00 30 14 01 00 00 0f ac 04 01 00 00 0f
0050 ac 04 01 00 00 0f ac 02 28 00 2d 1a ef 09 17 ff
0060 ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0070 00 00
00 00 00 00 3d 16 95 0d 11 00 00 00 00 00 0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7f 08 0090 04 00 08 00 00 40 00 40 bf 0c 91 59 82 0f ea ff 00a0 00 00 ea ff 00 00 c0 05 00 00 00 00 00 c3 03 01 00b0 3c 3c dd 07 00 0b 86 01 04 08 1b dd 18 00 50 f2 00c0 02 01 01 80 00 03 a4 00 00 27 a4 00 00 42 43 5e 00d0 00 62 32 2f 00

如果用這個16進位制的內容自己去解析報文,分析各個IE,是不是很頭疼?wireshark可以幫助你解決這個問題,下面介紹兩種方法:

1、使用命令列將hexdump檔案轉換為pcap檔案,再用wireshark開啟pcap檔案

將上述beacon內容儲存到beacon.txt檔案中,然後用text2pcap命令進行轉換:

text2pcap -l 105 beacon.txt beacon.pcap

引數“-l 105”是在指定報文型別,105代表的是LINKTYPE_IEEE802_11即要把beacon.txt的內容轉換為802.11格式的報文。然後用wireshark開啟beacon.pcap即可,效果如下圖所示:

2.使用wireshark圖形介面匯入hexdump檔案進行解析

具體步驟如下:

最終結果如下圖所示:

 

在進行轉換的時候需要注意一下幾點:

1、text2pcap工具只能接受一定格式的hexdump,更詳盡的用法:https://www.wireshark.org/docs/man-pages/text2pcap.html
2、出了802.11格式的報文外,text2pcap還可以處理很多種報文型別,詳見:http://www.tcpdump.org/linktypes.html
3、hexdump的內容開始要是802.11頭,結尾沒有4位元組FCS校驗,如果有請去掉,不然報文解析會有問題。
4、有時候我們列印報文可能並不是從802.11頭開始列印的,找到802.11頭,去掉前面的內容後會變成如下這種樣子:
0000   80 00 00 00 ff ff ff ff ff ff 40 e3 d6 cb
0020   fe d0 40 e3 d6 cb fe d0 70 29 7b 00 55 41 00 00
0030   00 00 64 00 11 01 00 06 50 61 72 72 6f 74 01 06
0040   98 a4 30 48 60 6c 03 01 95 05 04 00 01 00 00 20
0050   01 00 23 02 1b 00 30 14 01 00 00 0f ac 04 01 00
0060   00 0f ac 04 01 00 00 0f ac 02 28 00 2d 1a ef 09
0070   17 ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00
0080   00 00 00 00 00 00 00 00 3d 16 95 0d 11 00 00 00
0090   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00a0   7f 08 04 00 08 00 00 40 00 40 bf 0c 91 59 82 0f
00b0   ea ff 00 00 ea ff 00 00 c0 05 00 00 00 00 00 c3
00c0   03 01 3c 3c dd 07 00 0b 86 01 04 08 1b dd 18 00
00d0   50 f2 02 01 01 80 00 03 a4 00 00 27 a4 00 00 42
00e0   43 5e 00 62 32 2f 00 da e2 e8 16  

除最後一行外,有可能會出現每行不是16個位元組,如果手動去把每行搞成16個位元組並且把第一列每行的開始位元組索引搞對會非常費勁,並且還容易出現手誤,把某個位元組給刪掉的情況,影響工作效率。

下面我寫了一個程式transform來解決這個問題,有3種用法,如下:

a) ./transform src.txt dst.txt

b) cat src.txt | ./transform dst.txt

c) cat src.txt | ./transform (會將結果打印出來)

transform原始碼如下:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #define BYTES_PER_LINE (16)
  4 #define SPACE_PER_LINE (BYTES_PER_LINE)
  5 #define PREFIX_NUM (6)
  6 
  7 int process(char *src, char *dst)
  8 {
  9     static int line = 0;
 10     char *pchar = NULL;
 11     int offset = 0;
 12 
 13     if (NULL == src || NULL == dst)
 14     {
 15         printf("Err: src:%p dst:%p\n",src, dst);
 16         return -1;
 17     }
 18 
 19     offset = strlen(dst);
 20     if (0 == offset)
 21     {
 22         sprintf(dst,"%06x ",line*BYTES_PER_LINE);
 23         offset = strlen(dst);
 24     }
 25 
 26     pchar = strtok(src, " ");
 27     while (pchar = strtok(NULL, " "))
 28     {
 29         /* solve problems caused by  Windows and linux line breaks \n \r\n*/
 30         if ((2 != strlen(pchar)))
 31         {
 32             if (!((3 == strlen(pchar) && pchar[2] != '\n') || 
 33                 (4 == strlen(pchar) && 0 == strncmp(&pchar[2], "\r\n", 2))))
 34             {
 35                 continue;
 36             }
 37         }
 38         else if ((strncmp(pchar, "\r\n", 2) == 0))
 39         {
 40             continue;
 41         }
 42 
 43         dst[offset++]   = pchar[0];
 44         dst[offset++] = pchar[1];
 45         if (((offset - 1 - line*2) % (BYTES_PER_LINE*2 + PREFIX_NUM + SPACE_PER_LINE -1)) == 0)
 46         {
 47             dst[offset++] = '\n';
 48             line++;
 49             sprintf(&dst[offset],"%06x ", line*BYTES_PER_LINE);
 50             offset += PREFIX_NUM + 1;
 51         }
 52         else
 53         {
 54             dst[offset++] = ' ';
 55         }
 56     }
 57 }
 58 
 59 int main(int argc, char *argv[])
 60 {
 61     FILE *fpsrc = NULL;
 62     FILE *fpdest = NULL;
 63     char buf[1024];
 64     char *pchar = NULL;
 65     int ret = 0;
 66     char context[65535] = {0};
 67     int offset = 0;
 68 
 69     switch (argc)
 70     {
 71         case 1:
 72         /* Read from stdin and write to stdout */
 73         case 2:
 74         {
 75             /* Read from stdin and write to dest file */
 76             memset(buf, 0, sizeof(buf));
 77             while (fgets(buf, sizeof(buf), stdin) != NULL)
 78             {
 79                 ret = process(buf, context);
 80                 if (0 != ret)
 81                 {
 82                     return ret;
 83                 }
 84                 memset(buf, 0, sizeof(buf));
 85             }
 86             if (argc == 2)
 87             {
 88                 fpdest = fopen(argv[1], "w");
 89             }
 90             else
 91             {
 92                 fpdest = stdout;
 93             }
 94             if (NULL == fpdest)
 95             {
 96                 printf("Err can't open dst:%s\n", argv[2]);
 97                 return -1;
 98             }
 99             break;
100         }
101         case 3:
102         {
103             /* Read from src file and write to dest file*/
104             fpsrc = fopen(argv[1], "r");
105             if (fpsrc == NULL)
106             {
107                 printf("Err: can't open src:%s\n",argv[1]);
108                 return -1;
109             }
110             while(!feof(fpsrc))
111             {
112                 memset(buf, 0, sizeof(buf));
113                 fgets(buf, sizeof(buf), fpsrc);
114                 ret = process(buf, context);
115                 if (0 != ret)
116                 {
117                     return ret;
118                 }
119             }
120         fpdest = fopen(argv[2], "w");
121         if (NULL == fpdest)
122         {
123             printf("Err can't open dst:%s\n", argv[2]);
124             return -1;
125         }
126 
127         break;
128         }
129         default:
130         printf("Err: argc:%d  Wrong number of parameters!\n",argc);
131         return argc;
132     
133         break;
134     }
135 
136     fputs(context, fpdest);
137 
138     printf("\ntransform success!\n");
139 }