『008』gdbserver 失灵?长达半个月的 BUG 寻找!
总结反思
先写总结,总体看下来,推测的还是比较顺风顺水的,但是仍然消耗了大量时间,主要有以下不足。
1. 首先应该在 pwntools
下面提交 issue,主动出击
2. 应该试一下不同版本,不同系统,不同内核,然后再去怀疑别的包,不然就如同大海捞针。
3. 看来是要定期备份系统了~
故事的开始
和往常一样,组会结束后的两天,继续开始我的不务正业——pwnable.kr
刷题。然而arch
你懂的,麻烦总是不经意间出现。就是这么平常的日子里,我发现pwntools
里面的gdb.debug
不能用了,故事就这样开始了。
嫌疑犯一: pwntools
因为我是个正常人,肯定首先就会觉得是pwntools
自身的问题啦,应该有人已经发现这个问题了吧。于是上pwntools
的github
官方库中看了一下,竟然没有相关的issues
,两种可能:要么我是第一个受害者,要么我错怪pwntools
了。
人类总是懒惰的,我是人类,所以我也是懒惰的。面对这两种可能,我选择了做一个等等党,看看最近几天应该会有人提交issue
吧。可等了好些天,没有任何变化。
那就不是他的问题,可除了它还会是谁呢?在这上面花费了不少时间,但比较幸运的是,我之前几天正好做过pwnable.kr
的tiny_easy
,知道了pwntools.debug
原理是使用gdbserver
,所以顺理成章地,我开始怀疑起了gdbserver
。
嫌疑犯二: gdbserver
我试了一下gdbserver
,果然出了问题,卡在了<init_cache>
这个函数上。我去了 gdb 官网查看它的 bug,然而没有一点关于这个的踪影,所以我可能还是第一个受害者。这次我选择了主动出击,开始分析卡主的原因,但<init_cache>
函数我完全不了解啊。不过这也是奇妙之处,通过自己的各方面联系将自己本不了解的东西逐步推理出来,非常 cool ~
首先我发现了对于 64 bit 的程序,是可以正常运行的。换句话说,出错的都是 32 bit 的程序!但我测试了一下,最简单的 32 bit 程序是可以正常在 gdbserver 上使用的!但是我又看到之前函数卡住的地方,是和 gs 寄存器有关系的!所以我就立马想到:是不是出错程序都是有 canary 的 32 bits 程序呢?
自己写了非常简单的带有 canary 的 32 bits 程序,果然出了问题!!那么应该就是 gdb 的问题了,于是我去它的官网上提交了一个 bug,感觉自己酷酷的。说起来,那天正在参加导师组织的一个会议,我还是最主要的打杂者,负责接待,发水果,哈哈,当然大部分时间都是坐在那里干自己事情,当时基本就是花了这一个白天时间找到了这个 bug,然后提交。
果然,到了晚上,收到了官方作者的回信,作者可以复现这个 bug,但他也不知道原因。超级开心自己竟然提交了 gdb 的 bug,不过我自己解决不了,所以需要继续等一等官方解决咯。
嫌疑犯三: gdb
可是从那之后的五天时间,就没有一点消息了。于是,我开始尝试自己去解决这个问题。首先明确了一点,gdbserver 就是 gdb 套件的一个工具,所以 gdbserver 出了问题,那应该是 gdb 这个套件出了问题。
首先我更新了 gdb,然而还是会出错。不过这里有个小插曲,Arch 发布 gdb_10.1 的时候,竟然没有 gdbserver,好在之后更新里面加入了 gdbserver,也不知道什么原因。当时我还查了一下,gdb 10.1 之后确实取消了 gdbserver 对某些架构的支持,但 x86_64 肯定是有的啊,浪费了我两个多小时时间。
然后我去我的另一个许久没更新的 arch 上看了一下,发现是不会出错的,但是我更新完成后,带有 canary 的 32bit 程序竟然就不能在 gdbserver 上运行了。所以很明显,一定是某个安装包更新出了问题!
很明显是和 gdb 有关的安装包,但是我都降级了,很遗憾,还是出错!此外我还手动安装了 gdb 的低版本,发现还是出错!
嫌疑犯四: glibc
于是我想到,是不是 glibc 的问题?可是我试着将程序链接到低版本 glibc,还是出错。
救星: Ubuntu 20.04
没招了,怎么办呢?这个时候就要想到:在别的系统上面,会不会也是同样的问题呢?!
一共试了两个,第一个是在实验室的服务器上,很老的 Ubuntu 版本了,gdb 版本大概是 7 点几,试了一下,gdbserver 可以运行带 canary 的 32bit 程序。但是这个太老了,这个要不能成功我就怀疑人生了。所以我下载了 Ubuntu 20.04,试了一下,竟然成功了!
查看对应的版本:glibc 2.31 && gdb 9.2。OK,那么就在我的 Arch 系统上也用同样的版本,看看行不行!!试了一下,不可以,所以那就系统的问题?!
嫌疑犯五: kernel
查看了 Ubuntu 20.04 的内核,好像是 5.8.0,而我 arch 内核版本为 5.9.4 !
那么,降级!降到了 5.8.14,重启运行!竟然通过了!!那么就是内核的问题了!!
附录
- 使用 GDBSERVER
# terminal 01 : gdbserver localhost:11111 test # terminal 02 : gdb --> target remote localhost:11111
- 查看系统内核版本
uname -a
- Arch 降级内核
# 首先两种方法去获取旧版本 cd /var/cache/pacman/pkg https://archive.archlinux.org/packages/ # 最后一定要重启! sudo pacman -U linux-xxxxxxx reboot