如何反編譯Android 5.0 framework

CSDN發表於2015-12-22

在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中的所有類資訊,比如:方法,描述資訊,偏移列表等等,是一個非常核心的檔案。

相關文章