ARM的栈回溯(三):在 ida 里实时进行 arm 栈回溯

本系列文章共三篇。本文是第三篇,使用已有的知识,实现 arm stack unwind,给本系列完美地画上句号。

# ida arm unwind plugin

IDA 里有一个不常用的功能,叫打印栈回溯,使用的是常见的 ebp/esp 栈帧技术,没有对 ARM 进行适配,导致调试安卓 so 时完完全全是错的。本文编写一个 ida 插件,正确展示实时的 arm 栈回溯。

本文代码在:https://github.com/LeadroyaL/IDA_ARM_Unwind,欢迎 star。

设计思路:

  1.  总目标,对当前断点进行栈回溯,得到 pc 序列,进一步可以得到 crash-log 一样的栈回溯展示
  2.  检查运行环境,需要是 ARM 架构,需要处于调试中的状态
  3.  将当前 pc 加入序列
  4.  初始化VRSStatus状态,将各个寄存器的值设置正确,为 unwind 做准备
  5.  递归 unwind
    1.  根据当前 pc 找到当前 ELF 头部的大概位置,解析头部的一些字节,使用 pyelftools 得到第一个 PT_LOAD
    2.  .ARM.exidx.ARM.extab 一定在第一个 PT_LAOD 里,使用 pyelftools 解析它们的数据
    3.  根据当前 pc、List[EHABIEntry],找到对应的 EHABIEntry
    4.  解释执行对应的字节码,得到最终状态
    5.  最终状态的 LR 就是返回地址,判断 ARM 还是 THUMB,再决定是 -2 还是 -4,修正为上一条指令的地址
    6.  将计算好的 pc 加入序列
  6.  使用 pc 序列,寻找对应的 module、funcion,计算相对偏移,构造为 List[Frame]
  7.  绑定快捷键,画 GUI,抄的 https://github.com/ChiChou/IDA-ObjCExplorer 的代码

效果图,个人感觉还是非常好用的哈:

具体用途看仓库里的 readme 哈。

# 总结

三篇文章,虽然是按照开发的时间顺序写的,但发生顺序其实是反的,这个流程拖得挺长:

  1. 先发现 IDA 失效,于是准备写个插件;
  2. 写插件,研究栈回溯,发现 ARM 的栈回溯跟人不一样 (参考  原创andorid native栈回溯原理分析与思考
  3.  pyelftools 不提供 arm ehabi 的解析,于是自己实现数据解析(参考 https://github.com/llvm/llvm-project/blob/master/llvm/tools/llvm-readobj/ARMEHABIPrinter.h
  4.  libunwind 接入成本太高,于是自己用 python 写字节码的解释执行和 unwind(参考 https://github.com/llvm/llvm-project/blob/master/libunwind/src/Unwind-EHABI.cpp

把大量的规范从 c 移植为 python,整个下来花了我大量时间,但对 unwind 本身有了非常深刻的理解。

希望 elftools.ehabiida-arm-unwind-plugin 这两个轮子能为行业做贡献吧。

第一篇指路:https://www.leadroyal.cn/?p=1125

第二篇指路:https://www.leadroyal.cn/?p=1131

第三篇指路:https://www.leadroyal.cn/?p=1135

 


=============================================================
随着访客的增多,LeadroyaL在本站流量的开支越来越多了,曾经1元能用1个月,现在1元只能用3天。如果觉得本文帮到了你,希望能够为服务器的流量稍微打赏一点,谢谢!

发表评论

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

*

code