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结果如下:
ndiswrapper加载TL-WN322Gplus之殇-抓取802.11数据帧_第1张图片
在实在看不出结果的情况下,可以考虑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,参见下面的图片确认地址信息,以便和抓包结果比对:

ndiswrapper加载TL-WN322Gplus之殇-抓取802.11数据帧_第2张图片

最后,dmesg的结果如下:

ndiswrapper加载TL-WN322Gplus之殇-抓取802.11数据帧_第3张图片


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



你可能感兴趣的:(rap)