基于fp栈回溯

老生常谈,无需多言。

基于.eh_frame栈回溯

https://developer.aliyun.com/article/815064

栈回溯参考文章

https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html

.eh_frame 相关资料

据说记录了寄存器的变化,随便找个elf用readelf -wF 来看下里面是个啥。

重新选择方便调试的样本。断点下在JNI_OnLoad ,先看bt给出的完整调用栈,假设崩溃点出现0xeb9cc

0xeb9cc 各寄存器值

.eh_frame 该位置数据

看下有没有翻车

x29=0x0000007fcbc7b4a0 , CFA = x29 + 16 = 0x0000007fcbc7b4b0 , ra = *(CFA – 8) = *(0x0000007fcbc7b4a8)=0x00000076ebf03d98

frame #1 对应上了,拿到libart.so 的.eh_frame 数据。offset = 0x0000007fcbc7b4a8 – 0x76ebb87000 = 37 CD98

那这里如何去得到x29 寄存器呢,回想一个函数(BL)调用另一个函数的过程。


先设置ld寄存器,进入函数内部后,将ld寄存器和x29寄存器依次压栈,将x29 指向栈底,那么x29上的值就是caller的x29.

x29 = 0x0000007fcbc7b5e0 ,CFA = x29 + 16 = 0x0000007fcbc7b5f0 ra = *(CFA – 8) = *(0x0000007fcbc7b5e8) = 0x00000076e1a2b0e4

frame #2对应上了,OK 后续类似就不用做了。


pareto

未来什么方向不管,先做自己喜欢做的事情。

0 条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注