ndiswrapper加载TL-WN322Gplus之殇-抓取802.11数据帧

修改NDIS库的实现来抓取802.11帧看似简单,实则困难。原因就在于NDIS只是Windows网络驱动的一套框架,类似Linux的Netfilter,它看重的是接口而不是实现,特别对于小端口驱动,最终只要将数据和上层驱动接口即可,具体读写设备的逻辑完全对外是封闭的。而对于Windows平台上的TP-Link无线网卡驱动,正是小端口驱动的典范,因此别指望它大量调用NDIS函数,它只需要最终调用NdisMIndicateReceivePacket即可,而NdisMIndicateReceivePacket所做的就是调用Linux的netif_rx将数据包交给Linux,在此之前,802.11帧和以太帧的适配转换工作已经在“小端口驱动的实现”中完成了。
        那么在哪里可以看到802.11帧呢?我们不得不靠猜测来找到它。鉴于各个厂商的实现不一致,可以使用Windows开发工具箱中的dumpbin来查看具体的网卡驱动,我这里使用的是 athur.sys/netathur.inf/athurext.cat,dumpbin结果如下:

在实在看不出结果的情况下,可以考虑memcpy这个超级底层库函数,因为几乎所有的模块都涉及到内存拷贝,而数据帧从硬件到内存也会涉及到memcpy,当然这只是猜测,实现者完全可以不使用库函数,直接使用指针运算,然而这种实现难道可以商业化吗,因此我敢肯定商业代码中的帧拷贝操作[几乎]一定用了memcpy。
        然而问题来了,使用memcpy的操作太多了,到底哪个是复制802.11帧的呢?这就牵扯到了如何过滤802.11帧的问题了。这需要你对802.11帧格式有着深刻的理解,才能在茫茫内存中发现802.11帧。ndiswrapper的driver里面有个crt.c文件,封装C库供ntoskernel以及NDIS调用,修改其中的memcpy就好了,以下是我的一个修改,仅仅过滤802.11的纯数据帧,一种是FromAP的,另一种是ToAP的,关键不同点是第二个字节代表From AP和To AP:
noregparm void *WIN_FUNC(_win_memcpy,3)         (void *to, const void *from, SIZE_T n) { #ifdef DUMP_802_11  #define    80211_MINLEN    24 #define    80211_CTRL    0x88 #define    80211_TOAP    0x01 #define    80211_FROMAP    0x02     //最短的帧头24字节     if (n > 80211_MINLEN) {         int i = 0;         char *search = from;                 for (i = 0; i < n-1; i++, search++) {             //寻找802.11帧的控制字段;             //可能会将非802.11帧然而恰好匹配的也匹配进来             if (((*search & 0x000000ff) == 80211_CTRL) &&                 (*(search+1) == 80211_TOAP ||                  *(search+1) == 80211_FROMAP)) {                 if (n-i > 80211_MINLEN) {                     int j = 0;                     char *frame = search;                     //将其后的帧体打印出来                     printk("###### memcpy #####\n");                     for (j = 0; j < n-i; j++, frame++) {                         printk("%02X ", *frame & 0x000000ff );                     }                     printk("\n###### memcpy END#####\n");                 }                 break;             }         }     } #endif     return memcpy(to, from, n); }

上面的过滤算法不一定是最高效的,然而只求说明问题。除此之外,这个算法还有以下的问题:
1.字节匹配使用了遍历搜索,其实还可以使用诸如二分等方式优化;
2.不能解决802.11帧分批copy的情况,如果一个帧分好几次copy将无法得到整个帧,甚至帧头都无法取得;
3.如果Windows驱动程序根本就没有使用memcpy进行帧拷贝,比如使用DMA零拷贝技术。那此方法将完全失效;

重新 make -C $ndiswrapper_dir
运行 ndiswrapper -l确认下面的行
netathur : driver installed
        device (0CF3:1006) present

运行 modprobe ndiswrapper

配置wlan0的IP地址以及连接接入点,然后ping 190.168.1.100,参见下面的图片确认地址信息,以便和抓包结果比对:

最后,dmesg的结果如下:


这就说明,802.11数据帧已经被dump了下来。不管怎么说,总算是抓到了802.11帧,也是一件不容易的事,虽然还有很多改进的空间。如此之工作完成,以后就可以尽情分析802.11网络上的种种怪事了,还不错...



你可能感兴趣的:(网络技术)