老罗android oat,入门ART虚拟机(5)——OAT文件
Android安全交流群:478084054
先貼老羅的一張圖:
再摘一段老羅的描述:“作為Android私有的一種ELF文件,OAT文件包含有兩個特殊的段oatdata和oatexec,前者包含有用來生成本地機器指令的dex文件內容,后者包含生成的本地機器指令,它們之間的關系通過儲存在oatdata段前面的oat頭部描述。此外,在OAT文件的dynamic段,導出了三個符號oatdata、oatexec和oatlastword,它們的值就是用來界定oatdata段和oatexec段的起止位置的。”
老羅的這段描述,有些地方稍微有點不太準確。
符號oatdata、oatexec和oatlastword是動態符號表(.dynsym)中導出的,不是dynamic段導出的。
另外,oatdata和oatexec并不是OAT(ELF格式)文件中兩個獨立的段,而是分別位于第1個和第2個LOAD段中,這一點對比上面的.dynsym和下面的Program Headers Table就可以看出來了。
如何在OAT文件中找到一個類方法的本地機器指令呢?還是貼老羅的一幅圖,再結合上圖和老羅的一段描述(感謝老羅的博客)就可以大概理解了。
“首先根據類簽名信息從包含在OAT文件里面的DEX文件中查找目標Class的編號,然后再根據這個編號在OAT文件中找到對應的OatClass。接下來再根據方法簽名從包含在OAT文件里面的DEX文件中查找目標方法的編號,然后再根據這個編號在前面找到的OatClass中找到對應的OatMethod。有了這個OatMethod之后,我們就根據它的成員變量begin_和code_offset_找到目標類方法的本地機器指令了。”
下面以Android 6源碼為例,看一下OatFile::Open函數(art/runtime/Oat_file.cc):
可以看到,有兩個函數可以加載OAT文件:OpenDlopen和OpenElfFile。這兩個函數有什么區別?繼續摘老羅的博客(非原文,簡化了一下):“ART運行時會為類方法生成相應的本地機器指令,這些本地機器指令可能會調用外部函數,這就涉及到模塊依賴問題,就好像我們在編寫程序時,需要依賴C庫提供的接口一樣。ART運行時支持兩種類型的Backend:Portable和Quick。Portable類型的Backend通過靜態鏈接器生成本地機器指令,通過重定位技術來處理模塊依賴問題。這對熟悉linker動態加載過程的程序員來說很容易理解。而Quick類型的Backend生成的本地機器指令用另外一種方式來處理模塊之間的依賴關系。簡單的說,就是ART運行時會在每一個線程的TLS(線程本地區域)提供一個函數表,本地機器指令通過它來調用其它模塊的函數。這使得生成的OAT文件在加載時不需要再處理模塊之間的依賴關系,也就省去了重定位,不需要通過系統的動態鏈接器提供的dlopen來加載。這樣OAT文件在加載時就會更快,這也是稱其為Quick的緣由。”。
仔細看一下OatFile::Open,會發現參數executable為false時,不會執行OpenDlopen。什么情況下executable為false?如果是dex2oat過程中調用的OatFile::Open,參數executable就為false。
調用OpenDlopen加載非executable的OAT文件可能會失敗,具體看函數注釋:
主要看OpenElfFile函數:
繼續跟OatFile::ElfFileOpen(省去了一些出錯處理代碼):
先Open文件,再Load加載,然后調用FindDynamicSymbolAddress找到OAT文件中的oatdata、oatlastword、oatbss、oatbsslastword四個符號的地址。
其中Open和Load的過程類似于linker的dlopen過程的,但沒有重定位,僅僅是將OAT文件的LOAD段映射到內存,并解析出字符串表、符號表等重要信息的地址等等。
這里摘錄Roland_Sun博客對這個過程的一點總結:1)如果elf文件中包含了虛擬地址為0的PT_LOAD段,則證明它不是Boot Oat,而是一個普通的應用程序的oat,這時候該elf文件無所謂被映射到內存中的任何地方,其虛擬地址(p_vaddr)中記錄的是該段相對于文件頭的偏移;
2)如果elf文件中沒有包含任何虛擬地址為0的PT_LOAD段,則證明它是一個Boot Oat,必須被加載到一個指定位置(實際是緊接在Image之后),其虛擬地址(p_vaddr)中記錄的就是實際要被加載的絕對地址。
Boot OAT的Program Header:
一個普通應用程序的OAT的Program Header:
回到OatFile::ElfFileOpen,繼續看Setup函數。下篇筆記繼續。
總結
以上是生活随笔為你收集整理的老罗android oat,入门ART虚拟机(5)——OAT文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android sendmessage和
- 下一篇: 16福师计算机应用基础在线作业,16春季