0x00 前言
oat文件其实就是一种特殊的elf文件,更详细点说,就是拥有两个特殊段oatdata和oatexec的elf文件。而oatdata中则包含了dex的信息。
因此在学习oat文件格式之前,最好对dex的文件格式,以及elf的文件格式有一定的了解。dex的格式虽然我也不是很熟,毕竟很久之前看学习的了,但还是有印象的。elf的话,最近尝试so文件修复的时候,也看了不少..所以都贴几个链接算了。
dex:
http://bbs.pediy.com/thread-160260.htm
http://bbs.pediy.com/thread-208828.htm
elf:
https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
0x01 瞎逼记录
首先看下一般的elf的结构,wiki百科的图如下:
然后看下oat的文件结构,这是我根据罗升阳博客上的再画一次的图.
(感觉画一遍对理解有帮助23333)
然后,我们直接使用010查看下oat文件的结构。由于我的辣鸡测试机只是4.3版本,4.4的那台太卡了,都不想开了。所以我用的oat文件是从这http://bbs.pediy.com/thread-206230.htm找的....这篇文章也对oat文件结构分析的很好。
使用010中的elf template对文件进行分析。可以得到如下结果
从结果可以看出,在dynamic symbol table中确实看到了其中包含了oatdata,oatexec和oatlastword。但是在section 却没有看到oatdata 和oatexec对应的section。其实点开dynamic symbol table详细看就会明白的了。
这两个东东所在的section就是第4,5段,就是.rodata和.text段。
这是为什么呢?我又去看了下将oat文件加载到内存中源码。
看完就可以发现,其实在加载的时候,也是根据dynamic symbol来寻找的。所以我个人认为呀,那个oatdata和oatexec 段的命名,只是为了可以更加容易地理解在oat文件中是有两个section专门来保存oatdata和oatexec的内容,而不是有两个叫做oatdata和oatexec的section。
从整体上看完了,接着就仔细看下这些“与众不同”的地方,个人感觉这之后的才算是真正的oat格式。
首先,“oatdata”段中,第一部分是oat头,可以从源码中可以看出oat头的结构。
|
|
在oat头之后,紧接着的就是image空间,这也是可以从源码中看出的。
在老罗的博客文章中,header接着应该就是一堆dex相关信息。但是在我找到的这个oat文件中,header头之后还存在一段数据‘ key_valuestore’。这应该是不同版本造成的。上面的oat代码是4.4源码的,但我拿到的这个样本是在5.1.1的,而在5.1.1中,源码也发生了点不同:
接着就是dex的信息了,dex其中包括的信息有:
dex_file_location_size
dex_file_location_data
dex_file_checksum
dex_file_offset
methods_offsets_pointer
根据这几个信息,就可以定位到dex文件的位置,然后再根据dex文件结构,提取到了dex文件的大小,就可以从oat文件中提取出dex文件。
比如我拿到的这个oat文件的dex_file_offset的值为0x938,而这个段的偏移为0x1000,那么dex的地址就为0x1938。如下图:
然后根据dex文件结构,得到dex的文件大小所在的偏移为0x20,在这个例子中则是0x1938+20 = 0x1958。得到大小为0x98128。最后根据其实地址为0x1938,大小为0x98128,dump下就可以获得dex文件。
其实oat格式的知识还不只这些,但这里仅仅是从大体结构了解到dump出dex文件。