如何反編譯Android 5.0 framework
來自專欄 Android資料庫
在Android平台,對於和硬體交互相關的模塊來說,比如:和雙卡對應的Telephony模塊、和拍照對應的Camera模塊,以及Bluetooth模塊等等,不同廠商會不同程度的修改Android framework層對應的原生模塊代碼來達到他們自己的目的,這就給應用層的開發人員帶來了讓他們很頭疼的適配問題,嚴重會導致Crash等問題。為了更好的適配,我們不得不對framework層進行反編譯,在Android更新到5.0後,開發人員對framework的反編譯也出現了新的變化。
一、相關背景介紹
在5.0以前,我們可以直接從手機system目錄導出的framework文件夾根目錄里找到相關的odex文件或者相關dex文件(解壓jar文件或apk文件得到),然後通過smali和dex2jar等工具就可以成功反編譯得到我們所需要的東西。但到了5.0,出現了兩個問題。
1. 以前分散在framework文件夾根目錄里的那些odex文件全部集中在了framework文件夾中的arm(或arm64)子文件夾中,而且通過正常的反編譯發現這些odex並不是像5.0以前一樣是我們所需要的東西。
圖:arm文件夾里的各種odex文件
2. 在arm(arm64)子文件中出現了兩個我們在5.0以前沒有見過的東西:boot.oat文件和boot.art文件,這兩個文件引起了我們的興趣,也是我們接下來分析的重點。
圖:arm文件夾里重要的boot.oat文件和boot.art文件
二、對oat文件的分析
說到這個oat文件和art文件,我們不能不提Google在4.4版本以後新引入的ART運行時,這裡簡要的說一下:我們都知道在4.4以前,Android應用程序運行的核心基礎是Dalvik虛擬機,這個Dalvik虛擬機原先是Apache開源的一個JVM的優化版本,而Google又對Dalvik虛擬機進行了特別的優化來適應Android系統,所以Dalvik虛擬機本質就是JVM。
儘管Google花了大力氣優化Dalvik虛擬機,但是效果目前來看還不能讓Google滿意。為了Android系統的流暢度能更上一層樓,在Android進化到4.4版本時,Google決定拋棄Dalvik虛擬機引入全新的ART運行時。其實,ART運行時依然還是Java虛擬機的實現,只是ART運行時更高效更好用。
圖:左邊對應Dalvik虛擬機,右邊對應ART運行時(原圖出處:羅昇陽——Android ART運行時無縫替換Dalvik虛擬機的過程分析)
和Dalvik虛擬機相比,ART運行時執行的是本地機器碼,雖然Dalvik虛擬機也使用JIT(Just-In-Time)將dex位元組碼翻譯成本地機器碼,但是是在應用程序的運行過程中進行的。所以在效率方面還無法和ART運行時相比,ART運行時會在應用程序安裝的時候就通過dex2oat將dex位元組碼翻譯成本地機器碼,而這個由ART翻譯出來的本地機器碼會對應著一個oat文件。
圖:函數run_dex2oat通過調用dex2oat來將dex位元組碼翻譯成本地機器碼
其實,oat文件是一種特殊的ELF文件(關於ELF文件的具體內容可以Google相關內容),通過前面的介紹可以知道它包含本地機器碼(從dex翻譯而來),此外還包含有原來的dex文件內容,本質上它依然是一種預編譯文件。這就告訴我們,oat文件就是把過去的很多dex文件一起合併輸入然後由ART運行時在安裝時翻譯成本地的機器碼然後再打包轉換輸出就OK了。
同樣的道理,我們知道system分區的文件都是在廠商在壓制ROM時打包進去的, framework文件夾裡面的內容尤其是各種dex文件等會在系統啟動後通過arm(或arm64)子文件夾里的boot.art文件來指定啟動一個ART運行時實例,然後把這些classes.dex等dex文件合併輸入到ART再翻譯成本地機器碼打包成oat文件,這就是我們需要的核心文件boot.oat的大致生成過程(具體的過程比較複雜,詳細情況可以自行Google相關內容)。到此,我們簡單的介紹了oat文件的來歷,oat文件里有什麼,以及oat文件的生成過程。
三、反編譯的核心:「拆開」oat文件
有了以上的了解,我們可以知道,反編譯boot.oat文件的核心步驟就是把之前很多dex合併起來生成的oat文件拆開。之前我們在oat是怎麼來的時候提到過,ART運行時會通過dex2oat把很多dex文件合併打包然後翻譯轉換成oat。所以相同的道理,如果要有一個oat2dex工具就好了。可喜的是,真的有oat2dex工具的存在,有了這個工具,我們就可以把我們需要的boot.oat文件給拆卸開了。
在拆開boot.oat文件後,會在原來的arm(或arm64)文件夾里再自動生成兩個子文件夾:dex文件夾和odex文件夾,而這兩個文件夾中的文件幾乎一樣,都是一些dex文件,在這些dex文件中,一定有你需要的dex文件。接下來的工作就和以前的步驟一樣了。
圖:反編譯oat的核心:oat2dex.jar文件
圖:反編譯成功後自動生成的dex和odex子文件夾
圖:反編譯成功後在dex文件夾里生成的dex文件
四、總結
Android 5.0的反編譯問題,其實質和以前並沒有發生變化,只是在過程上繞了一個彎,而這個彎就是如何拆解ART運行時帶來的oat文件,在我看來,oat文件依然是一個和apk文件類似的東西,它包含了apk或jar中的所有類信息,比如:方法,描述信息,偏移列表等等,是一個非常核心的文件。
推薦閱讀:
※Play 應用新圖標 & 4月 Android 系統分布
※摩托、三星等品牌同一型號的android手機為什麼不能像蘋果手機一樣採用統一的硬體,固件(rom)可以通刷?
※如何優雅地使用BlackBerry 10?
※BAT哪家Android的APP 水準最高?
※Android 靜態代碼分析工具