在某一个平行宇宙中,各位读者大大现在看到的应该是一篇关于网络协议的文章。
这个平行宇宙与当前宇宙的分叉点来源于2个小时前,我点了一下Wireshark抓包,一刹那,蓝屏了,那篇文章中近一段时间写的内容没了。
我差点拍案而起,WTF!保存啊保存,一个不留神就忘记了。
事情是这样的:
我想抓一些DHCP协议的数据包,于是将网卡禁用,然后开启Wireshark,打算把一会儿启用网卡后的通信过程抓下来。然而等我双击网卡开始抓包的一瞬间,蓝了!
捶足顿胸之际,不小心瞅见了蓝屏界面上蓝屏的驱动程序名字:npcap.sys,看来是Wireshark用的抓包驱动有问题呀!
这家伙害我害得这么惨,我不打算放过它,决定找出来到底这程序哪里写的有问题。
等了几分钟,电脑重启后,在C:\Windows目录下找到了系统崩溃后产生的核心存储文件:MEMORY.dmp,这个文件是操作系统崩溃后,Windows将内核的数据、所有进程、线程的执行上下文进行了保存,相当于对“案发现场”进行了“拍照”,用于事后定位问题。
注意,这个得提前设置好才会存储,默认情况下只会存储一个很简单的mini dump文件,不利于问题分析。
祭出内核分析神器:WinDbg,来加载分析dump文件。
因为已经知道崩溃位置位于npcap.sys文件,所以先去简单了解了一下这个东西。
Linux上咱们使用tcpdump抓取数据包时,底层使用的核心库就是libpcap,这是一个开源项目,在Windows上对应的就是winpcap。后来在Win7之后,Windows上使用了更现代化的抓包接口,Wireshark默认使用npcap来代替了传统的winpcap。
既然是开源项目,事情就好办了,有源码,有PDB符号文件。
源码大家知道,PDB文件可能有些人不知道。我们知道C/C++这类语言编译完成后,所有的函数名字、参数、数据结构定义等信息就丢失了,剩下的都是CPU指令了。那万一程序出了问题程序员怎么分析呢?这就需要pdb文件了,pdb是程序数据库的意思,这里面有前面说的那些信息。
在npcap项目的官网,找到了npcap.sys驱动程序对应版本的npcap.pdb文件,下载后,载入WinDbg中,可以看到程序崩溃的函数调用堆栈:
看到了吧,有了PDB文件,连源代码路径都显示出来了。
在GitHub上找到了这个openclos.c文件,定位到最后导致崩溃的函数:NPF_FreeCapData
具体是崩溃在哪一行呢?
回头看看windbg可以告诉我们具体那一行指令的地址,在上下文的RIP寄存器中可以看到:
看一下这个位置的指令是个啥:
导致蓝屏的是这一条指令:
- mov rbx, [rdx+18h]
这条指令的意思是把rdx+18指向位置的内容,读取到rbx寄存器中。又看了一下崩溃代码是内存访问异常,那肯定就是rdx+18这个地址有问题了。
地址有问题,那现在rdx是个啥呢?
我去,居然是0,空指针NULL啊!那不崩溃就怪了!
结合汇编指令和数据结构定义,就能锁定源码中的具体位置了:在源码中的三级指针访问中,第二级指针的pNBLCopy字段为空!而代码中又没有判断为空指针的情况,就崩溃了~
再次结合函数调用栈和GitHub中的源代码,可以看到这是在清理释放抓取到的所有数据包时出现的问题,看下面代码,这是在一个循环中,挨个释放每个数据包所占据的资源,所有数据包以双链表形式串联了起来。
问题分析到这里,我已经按捺不住心里的激动了,难道我发现了一个0day漏洞?要知道,驱动程序空指针bug用的好可是能做内核级攻击的!一个漏洞都是值不少$的。
刚刚幻想了1秒钟,马上清醒过来,等等,我这版本好像不是最新的,我康康最新的版本还有没有这个问题。
结果泼了我一盆冷水,新的版本,已经增加了对这个指针是否为空的判断了:
哎!与财富擦肩而过~
本文转载自微信公众号「编程技术宇宙」,可以通过以下二维码关注。转载本文请联系编程技术宇宙公众号。