分析固件中so文件的问题函数
0x0 引子
前段时间在学习《揭秘家用路由器0day漏洞挖掘技术》的时候,在3.1.2章节中,针对于so库中问题函数没有详细分析,我在尝试分析问题函数时,遇到了一些问题,这里把之前的记录分享出来。
0x1 分析工具
按照正常情况,工具应该是很简单的,gdb+IDA配合Qemu即可,但是我在分析的时候,由于IDA只可以分析主程序,而不能进入到so文件,如果直接分析so文件,是没有办法断下来的,这是因为so文件加载的基址未知。所以我最终选择使用gdb进行分析,同样,gdb中,下载断点还是没有办法断下来(可能是由于偷懒,使用的是软件包方式安装的gdb的原因),最后,在版主@gjden的提示下,重新编译了gdb,方能开始调试。编译gdb的方法比较简单,网上有一堆,这里不再啰嗦。下图是我编译后的gdb。
0x2 分析之旅
通过错误提示,我们可以使用IDA定位到错误函数,apmib_init()函数,该函数位于apmib.so库中。
接下来,直接动态调试,首先连接gdb,并在跳转到该函数前设置断点。
继续运行,运行到断点处。
这里我们可以看到,即将要跳转到$t9寄存器中存储的地址,此地址通过分析为_apmib_init()的地址,可以在IDA中看到。
我们一直执行到0x48e968的跳转,可以观察到$t9寄存器内的地址已经变成了其他段内。
对该地址下断点,继续运行。
通过参考IDA,我们知道在so中,apmib_init()函数的地址偏移为0x78f4,由于加载地址不确定,所以我们无法下断点,但可以判断出,目前断点断下来的位置,并非是此函数入口,所以我们watch $t9寄存器,并多次继续运行,观察$t9寄存器内的值,最终,寄存器内的值变成了0x7679d8f4,与问题函数差了正好0x76796000的偏移(这个值即为so的基址)。这里如果大家有更好的办法能快速执行到问题函数,欢迎在评论里指出。
我们可以查看此地址处的指令与内存值,通过对比判断是否为问题函数。
以上截图的对比说明我找对了位置。接下来分析问题函数。
通过静态分析,我们知道,是由于apmib_init()函数的返回值为0,才会导致程序报错,那么我们倒着看,只需关注$v0寄存器即可。
从图中可以看到,$v0寄存器的值即时$v1寄存器的值,我们需要关注$v1寄存器,对$v1寄存器的赋值,来自于四条路径,我们期望的值是$v1==1,实际情况为0,这里为0的两个跳转为0x7679d95c和0x7679e200,通过动态跟踪,程序是在0x7679d95c处进行了跳转,并由于mips是流水线模式,$v1被填充为0。
关于延迟槽,参考:
https://blog.csdn.net/groundhappy/article/details/71711938
通过分析,这里本不应该跳转,即$v0不应该为0,所以通过函数调用栈,可以确定问题发生在了0x7679d950处调用的函数中,我们去分析调用的spmib_hwconf()函数即可。
0x3 后记
至于绕过问题函数的办法,可以参考书中的劫持函数动态库的方法。在分析动态库的时候,之前过于相信工具,没有意识到工具可能会有问题。最后,要感谢@gjden和@仙果前辈的指点,少绕了一些坑。
原文作者:sudozhange
原文链接:https://bbs.pediy.com/thread-248865.htm
转载请注明:转自看雪学院
更多阅读: