Android安全交流群:478084054
接上篇笔记。
先贴一下OatFile::Setup函数(去掉了所有的错误检查代码,这样更清晰)
在oat data的开始位置是OatHeader,Begin()返回的就是上篇笔记中解析出的oatdata符号的地址。
OatHeader中的主要内容如下:
以一个实际的OAT文件为例:
可以看出,该OAT文件中包含一个DEX文件,该OAT文件就是由该DEX文件经过dex2oat生成的。
oat exec的偏移是2000h,该偏移是相对OatHeader(偏移为1000h)来说的,所以oat exec的文件偏移是3000h。
验证一下:
接下来是一系列的bridge和trampoline代码偏移,以后学习ART执行类方法时再说。
继续看Setup函数,跳过OatHeader,再跳过key_value_store,再后面就是DEX文件的相关内容了。
什么是key_value_store?dex2oat在将DEX转换为OAT的过程中,会在OatHeader后面填充一些key-value对,内容诸如“dex2oat-cmdline”等等:
继续看Setup函数,接着是一个for循环,依次解析每一个DEX文件的信息。
还是以实际的OAT文件内容对比着来看代码。
先是一个记录DEX文件位置的char数组,以及这个char数组的大小。然后是DEX文件的校验和。
再然后是DEX文件的偏移,这里的E8h是相对OatHeader来说的。OatHeader的偏移是1000h,所以DEX文件的偏移是10E8h。
再然后是一个偏移数组class_offs,因为相应的DEX文件中共有13个class(相应DEX文件的header中,class_defs_size的值为13),所以数组的大小是13。而数组中的每一个偏移值指向一个数据结构,这个数据结构记录了相应的class的信息,尤其是记录了其methods偏移的code_offset等等。
下图是该DEX文件中包含的13个class。
下面看一下这个偏移数组class_offs的具体的值:
以class_offs[1]为例,偏移是15BCh,加上OatHeader的偏移1000h,所以总的偏移是25BCh。
那么这块内容就记录了oat_class[1]的信息。
状态值为9,表示“Class init in progress”。
该类包含两个方法,这两个方法对应的native代码的偏移分别是206Dh和20E5h(相对OatHeader的偏移)。
再回去看Setup函数的代码,class_offs数组的偏移位置赋值给了methods_offsets_pointer,然后在创建OatDexFile对象时作为参数传入。
在OatDexFile的构造函数中,将该值赋值给了成员变量oat_class_offsets_pointer_。
该成员变量在后续ART查找类和方法的过程中会用到。
完。
网友评论