查看原文
其他

堆栈别乱用

梨树生果 看雪学院 2021-03-07

本文为看雪论坛优秀文章

看雪论坛作者ID:梨树生果 



引言



在做开发中,可能根据某些特定功能的实现,需要嵌入一段shellcode的汇编代码,当然,前提是你需要有一定的汇编基础。

在实际的逆向分析中,理解汇编的指令真的不是很难,无非就是读写、比较、计算数值,操作堆栈、操作寄存器的一系列的操作,如果遇见不会的指令上网查询一下就一目了然了。

但是当你真正的去实现一段汇编代码的功能时,你可能会遇见一些让你头疼的坑,当然可能这个坑就是你自己挖的,没办法你挖的你就得负责填上。


异常问题环境相关描述


 
实现功能:自写arm汇编指令调用dlopen函数。

问题手机:经测试vivo/oppo、CPU骁龙660、系统Android 8.1,需要同时符合这三点要求的都会中招。


定位问题点





最后锁定到问题点在__dl__ZN12LinkerLogger10ResetStateEv函数中的VST1.8 {D16}, [R0@64]!指令,当执行该指令时会出发"SIGBUS"错误信号导致程序崩溃。


分析过程


 
首先看一下错误信号"SIGBUS"的含义,通过搜索得知,该错误表示"未对其的访问" ,分析调试代码,第一个想到的就是“dlopen”的第一个参数字符串文件路径,该字符串不是4字节对齐,因此把修改字符串文件路径进行对齐,但是错误继续出现。

与此同时在对函数的进一步跟踪发现,出错的__dl__ZN12LinkerLogger10ResetStateEv函数,根本未使用这个字符串文件路径,所以可以肯定是问题点不在这里,失去了线索,一度陷入迷茫中......

带着一份执着,我又调试运行了几次,发现问题每次都出现在VST1.8 {D16}, [R0@64]这条指令上,这不是一条常用指令到底什么意思呢?

带着疑问去找到了答案,这是arm汇编里面的VFP浮点指令操作,该条指令的意思是把D16寄存器的值赋值到R0寄存器指向的地址中。

(知识点介绍:VFP指令集操作的是高精度的浮点值,所以他的寄存器是按64位8字节方式操作的,即一个“QDWORD”值,关于VFP信息参考连接:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204ic/Bcfhdhgd.html


从上图我看一下D16寄存器的值的来源,指令为VMOV.I32 D16, #0,从指令中解析出D16寄存器的值等于“0x0000000000000000”。

然后再来看一下R0寄存器值的来源,指令MOV R0, R4表示R0寄存器的值是R4寄存赋值过来的,而从指令 ADD R4, SP, #8中获得R4指令是SP+8的地址,由此可见我们R0寄存器实际指向的地址是SP+8。


从图中我们可以看出R0的地址为0xFFA1660C,那执行VST1.8 {D16}, [R0@64]指令实际上就是吧地址0xFFA1660C、0xFFA16610这两个堆栈地址指向的值置0,分析到这一步,如果是聪明的人应该就知道问题点了,谁让我笨呢!

没有看出来,好吧,既然没看出来我没就用笨的方法来吧,只要努力笨鸟也会先飞的,又思考了一下,决定写个demo,正常掉一下对dlopen,在用IDA逆向跟踪一下:

        

通过上面的图看出当前R0寄存器的值为"0xFFA177E8",再仔细看一下出错的时候R0寄存器的值“0xFFA1660C”,再仔细想一下错误提示“未对其的访问“,在想一下VFP浮點指令集是64位操作数的特征,最后再结合一这个图:


突然茅塞顿开了是吧!就是我们的R0寄存器指向的地址没有对齐导致的“SIGBUS”错误,“0xFFA1660C”地址在64位的操作运算中就是非法的操作,之前我们知道R0的来源是堆栈地址,那接下来就看看我自己编写的汇编代码中操作堆栈的位置:


追溯起源,从图中可知R0~R7一共是8个dword值,在加上一个LR,一共是9个dword值压入堆栈,就是这里导致后面VST1.8 {D16}, [R0@64]指令执行出错,带着好信的心里,我特意看了一下其他正常函数的堆栈操作,都是按照8字节对齐的。

于是乎各种感叹,学艺不精啊!~好了问题找到了,那就按8字节对齐的方式去操作堆栈,如图:


由于R0~R3在这里主要的用途就是传参寄存器,其自身就是可变的,所以不考虑这几个寄存器,只把R4寄存器和LR寄存器进行了保存,最后生成项目,重新运行程序,程序没有崩溃正常运行,到这里我们终于解决了问题,仿佛有些感动的泪水,毕竟在查找这个问题的时候所花的时间和经历,对此刻来说都是值得的。

在前面我说过,只有在vivo/oppo、CPU是骁龙660、系统为Android 8.1的手机才会出现这样的错误,因为在实际中我做过其他机型、其他CPU及其他系统版本的测试都没有问题。

个人认为可能是有viov/oppo厂商在定制该种配置手机的ROM的时候可能是添加/未添加某种处理机制产生的现象,当然我们不能说这是人家厂商的问题,我只能说是自己的粗心与马虎给自己造成的问题。

但能遇见这样的问题也并不是一件坏的事情,塞翁失马焉知祸福?我温习了旧知识,同时也学习了新知识。


- End -






看雪ID:梨树生果

https://bbs.pediy.com/user-467468.htm 

*本文由看雪论坛  梨树生果  原创,转载请注明来自看雪社区




推荐文章++++

应急服务辅助工具与系统溯源思路

利用auxv控制canary

未知黑客团队钓鱼样本分析

使用Binary Ninja去除ollvm流程平坦混淆

某盗链App逆向




好书推荐






公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



“阅读原文”一起来充电吧!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存