这篇文章上次修改于 225 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
安卓中base.odex文件本质上是一个ELF文件,由系统对原本的apk优化所生成
在使用stackplz打印堆栈的时候,有一些栈是base.odex的,同时也能看到有boot.oat的,也就是说如果用stackplz对odex或者oat下断,也是能用来打印一些内容的
比如搞清楚有些方法到底有没有被调用,堆栈情况;当然直接打印参数是不太现实的,但有个曲折的方法,定位到native操作数据的地方...
不过有个问题,怎么知道java方法在odex/oat中的偏移呢?
stackplz能解析到信息,是因为libunwindstack从odex/oat中解析了信息,这些信息位于odex/oat的.gun_debugdata
部分,然而直接使用IDA打开odex/oat却不能解析出来java方法有关的信息
如何处理?
- 用7z打开odex/oat文件,直接把
.gun_debugdata
的内容解压出来 - 根据实测,解压出来后是xz压缩的内容,所以再用7z解压一次
- 上一步会得到一个elf文件,这个时候再用IDA去解析,就可以看到java方法在odex/oat中的偏移情况了
tips: 后面的数字是函数大小
到这一步基本上够用了,拿到这些偏移,就可以对对应的文件下断了
如果还想把这些符号信息合并到odex/oat怎么办呢,也就是方便在IDA中直接查看?
一个方法是,把gun_debugdata最后提取的elf信息导出,也就是
- File -> Produce file -> Dump database to IDC file
这样会生成一个idc文件,保留idc文件中有关set_name的调用即可
然后IDA打开odex/oat后,再选择File -> Script File执行修改后的idc脚本即可
#!/bin/bash
# 1. use 7z unzip .odex file .gun_debugdata section
# 2. use 7z unzip .gun_debugdata section file (xz format)
# 3. use IDA load unzipped file, then File -> Produce file -> Dump database to IDC file
# 4. ./gen_set_name_idc.sh input.idc odex_use.idc
# 5. use IDA open odex/oat file, then File -> Script File to load odex_use.idc
gun_debugdata_xz_unzipped="$1"
idcname="$2"
cat > $idcname << EOF
#include <idc.idc>
static main() {
EOF
grep 'set_name' $gun_debugdata_xz_unzipped >> $idcname
echo "}" >> $idcname
效果如下:
要更完整还需要进一步创建函数等等...
没有评论