IDAPython脚本分享 - 自动在JNI_OnLoad下断点

本文介绍了一种使用IDAPython脚本自动定位并调试Android应用中JNI_OnLoad函数的方法,提高了逆向分析So模块的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自动在JNI_OnLoad下断点

脚本背景
  • 在Android逆向的过程中,一个很常见的场景就是我们需要分析So模块的JNI_OnLoad函数,每次我们使用IDA进行调试的时候,都要手动的找一次 libart.so(ART虚拟机)中调用JNI_OnLoad函数的位置,重复又麻烦,于是就用脚本把这个相对固定的过程用IDA Python脚本固化下来,提高效率,顺便跟大家分享一下。
脚本使用注意事项
  • IDA载入分析 libart.so 完毕之后(实时附加调试的时候,可以在IDA切换到这个模块)
  • 针对于ART虚拟机的,Dalvik虚拟机的需要对应修改一下(Dalvik虚拟机渐渐远去,我就不提供修改版本了)
  • 开发测试环境为Nexus 5X AOSP 6.0.0_r1
脚本思路
  • 通过阅读 libart.so 相关源码可知,在调用So模块的JNI_OnLoad函数之前,代码中会有日志输出,有参考字符串 “[Calling JNI_OnLoad in”
  • 通过 IDAPython 接口API,在 .rodata 段搜索上述的字符串,找到偏移地址
  • 通过 IDAPython 接口API,对上述偏移地址进行交叉引用参考,发现有2处引用参考,其中第二处是字符串定义处,因此取第一处
  • 通过交叉引用地址,使用IDAPython API 接口开始遍历整个函数(art::JavaVMExt::LoadNativeLibrary), 为了增加准确性,从上述找到的字符串参考位置开始进行 特征指令匹配
    1. 读取第二处的字节码 0xE494,根据 Thumb-2 指令的B指令编码规则(请参考我的另一篇博文),计算出目标跳转地址 0x24EBA0
    2. 跟踪进计算出来的地址 0x24EBA0,继续搜索特征指令 BLX R12
    3. 使用 IDAPython API接口直接在这个地址下断点即可
思路总结
  • 通过阅读对应部分源码,然后结合 IDA反汇编结果,先手工在IDA里面找一遍,然后考虑结合实际的一些特征值,配合 IDAPython API来进行脚本自动化 ~..~
脚本源码
### 如何在 IDA 中处理 JNI_OnLoad 函数 #### 定位 JNI_OnLoad 函数 为了定位 `JNI_OnLoad` 函数,可以利用已知的偏移量来计算其实际地址。对于给定的例子,如果 `libcrackme.so` 文件中的 `JNI_OnLoad` 函数相对于起始位置有固定的偏移,则可以通过简单的加法运算找到该函数的具体地址[^3]。 例如,假设 SO 文件加载基址为 AA238000H 并且 `JNI_OnLoad` 的 RVA (Relative Virtual Address) 是 00001B9CH, 那么真实的内存地址将是: ```assembly AA238000H + 00001B9CH = AA239B9CH ``` 一旦获得了这个确切的位置,在 IDA Pro 中就可以通过按 G 键并输入上述地址来进行导航;接着使用 F2 设置断点以便于后续调试操作。 #### 动态调试准备 为了让动态调试更加顺利,建议先让应用处于等待状态直到连接上外部调试工具再继续运行。这通常涉及到修改 Android 应用启动参数使其支持远程调试模式[^4]。具体做法是在命令行中执行如下指令: ```bash adb shell am start -D -n com.example.app/.MainActivity ``` 这里的 `-D` 参数指示系统暂停应用程序直至有一个合适的调试器被挂载上去为止。 #### 调试过程中注意事项 值得注意的是,尽管 `JNI_OnLoad` 常用于初始化 Java Native Interface 扩展功能,但它并非总是最先被执行的部分。实际上,在某些情况下,操作系统可能会优先调用 ELF 文件内的 `.init` 或者 `.init_array` 段里的其他代码片段[^2]。这意味着仅依赖于 `JNI_OnLoad` 来部署保护机制可能不够安全可靠,开发者应当考虑更全面的安全策略。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值