1. 程式人生 > >Android反編譯技術總結

Android反編譯技術總結

一、Apk反編譯工具及其使用方法

1.原理

學習反編譯之前,建議先學習一下Apk打包的過程,明白打包完成後的Apk裡面都有什麼檔案,各種檔案都是怎麼生成的。

這裡有兩篇AndroidWeekly中推薦過的好文章:

Apk技術也有非常多的技術可以學習,主要都是圍繞著如何減小體積,如何提高打包速度展開,這裡先不多說了。下面是一張基本的Apk檔案結構圖。

APK檔案結構

Apk檔案本質上其實是一個zip包。直接拿解壓工具解壓就可以看到其中包含了什麼。下面簡單介紹一下Apk檔案的結構。

  • AndroidManifest.xml:應用的全域性配置檔案
  • assets資料夾:原始資原始檔夾,對應著Android工程的assets資料夾,一般用於存放原始的網頁、音訊等等,與res資料夾的區別這裡不再贅述,可以參考上面介紹的兩篇文章。
  • classes.dex:原始碼編譯成class後,轉成jar,再壓縮成dex檔案,dex是可以直接在Android虛擬機器上執行的檔案。
  • lib資料夾:引用的第三方sdk的so檔案。
  • META-INF資料夾:Apk簽名檔案。
  • res資料夾:資原始檔,包括了佈局、圖片等等。
  • resources.arsc:記錄資原始檔和資源id的對映關係。

上面的截圖中每個檔案都是一個最基本的Apk
檔案應該包含在內的。但是直接把Apk當做zip解壓後的這些檔案是沒法直接閱讀的,畢竟他們都是經過了build-tools打包工具處理過的。我們直接用文字編輯器開啟這裡面的Manifest檔案看看。

反編譯前的Manifest檔案

反編譯Apk

的目的就是Apk拆成我們可以閱讀的檔案。通過反編譯,我們一般想要得到裡面的AndroidManifest.xml檔案res檔案java程式碼

2.Apk反編譯步驟

(1) ApkTool拆包,得到AndroidManifest和res等資原始檔

功能:拆解Apk檔案,反編譯其中的資原始檔,將它們反編譯為可閱讀的AndroidManifest.xml檔案res檔案。前面講過,直接把Apk檔案當做zip解壓,得到的xml資原始檔,都是無法直接用文字編輯器開啟閱讀的,因為它們在打包時經過了build-tools的處理。

這裡,我演示一下用apktool來拆解Apk檔案的基本方法,只需要在終端裡面執行下面的命令。

1

2

3

4

5

6

7

8

9

java -jar apktool.jar d yourApkFile.apk

// 注意`apktool.jar`是剛才下載後的jar的名稱,`d`引數表示decode

// 在這個命令後面還可以新增像`-o -s`之類的引數,例如

// java -jar apktool.jar d yourApkFile.apk -o destiantionDir -s

// 幾個主要的引數設定方法及其含義:

-f 如果目標資料夾已存在,強制刪除現有資料夾

-o 指定反編譯的目標資料夾的名稱(預設會將檔案輸出到以Apk檔名命名的資料夾中)

-s 保留classes.dex檔案(預設會將dex檔案解碼成smali檔案)

-r 保留resources.arsc檔案(預設會將resources.arsc解碼成具體的資原始檔)

下面我們看一下java -jar apktool.jar d yourApkFile.apk拆解後的結果:

Apk拆包結果

我們已經得到一個可以用文字編輯器開啟的閱讀的AndroidManifest.xml檔案、assets資料夾、res資料夾、smali資料夾等等。original資料夾是原始的AndroidManifest.xml檔案,res資料夾是反編譯出來的所有資源,smali資料夾是反編譯出來的程式碼。注意,smali資料夾下面,結構和我們的原始碼的package一模一樣,只不過換成了smali語言。它有點類似於彙編的語法,是Android虛擬機器所使用的暫存器語言。

這時,我們已經可以文字編輯器開啟AndroidManifest.xml檔案和res下面的layout檔案了。這樣,我們就可以檢視到這個Apk檔案的package包名、Activity元件、程式所需要的許可權、xml佈局、圖示等等資訊。其實我們把Apk上傳到應用市場時,應用市場也會通過類似的方式解析我們的apk。

note1:其實還有一種方法,可以省去每次解包時,都要輸入java -jar apktool.jar xxx這行命令,官網也有說明,就是將這個命令包裝成shell指令碼,方法見:https://ibotpeaches.github.io/Apktool/install/

note2:如果你在編譯的時候,發現終端裡面提示發生了brut.android.UndefinedResObject錯誤,說明你的apktool.jar版本太低了,需要去下載新版工具了。

note3:如果想要自己實現一個解析Apk檔案,提取版本、許可權資訊的java服務時,可以引用apktool.jar中的ApkDecoder,呼叫decode方法來實現。可以看下圖中,apktool.jar裡面有解析Apk檔案的實現。

apktool.jar

(2) dex2jar反編譯dex檔案,得到java原始碼

上一步中,我們得到了反編譯後的資原始檔,這一步我們還想看java原始碼。這裡要用的工具就是dex2jar

功能:將dex格式的檔案,轉換成jar檔案。dex檔案時Android虛擬機器上面可以執行的檔案,jar檔案大家都是知道,其實就是java的class檔案。在官網有詳細介紹。

用法:開啟下載的dex2jar-2.0資料夾,裡面有shell和bat指令碼,進入終端,就可以在命令列使用了。

1

2

3

d2j-dex2jar classes.dex

// 獲取classes.dex檔案在最前面說過,只要把Apk當做zip解壓出來,裡面就有dex檔案了

// 或者用apktool反編譯時帶上 `-s` 引數

執行後,可以看到classes.dex已經變成了classes-dex2jar.jar

進入dex2jar資料夾

note1:第一次下載下來後,在mac裡執行的時候可能會提示需要管理員的許可權,這裡我給這些sh指令碼chmod 777後,即可執行它。

root執行dex2jar

note2:寫完這一節的時候,我發現把dex轉換成jar已經有了更好的工具enjarifyhttps://github.com/google/enjarify這個工具是谷歌官方開源的用於反編譯dex檔案的。使用方法和dex2jar差不多,也是簡單的命令列操作。這個工具的主頁中也提到dex2jar已經是一個比較老的工具,在遇到混淆等等複雜的情況時,可能無法正常工作。所以這裡推薦大家使用enjarify這個工具。

(3) jd-gui檢視java原始碼

功能:這個工具不用多說,寫java的人都知道。有時候我們自己開發一個jar包給別人用,也會用它來檢視class是不是都被正確的打入到了jar內,我以前介紹的gradle自定義打包jar的部落格中也提到過它。

用法:下載後雙擊既可以執行這個工具,直接把上一步得到的classes-dex2jar.jar拖到jd-gui程式的介面上即可打開了,效果如下圖所示。

classes-dex2jar.jar

反編譯Apk步驟小結

反編譯一個Apk,檢視它的資原始檔和java程式碼,我們需要用到3個工具。

反編譯就是用這3個工具得到AndroidManifest.xml、res、java程式碼等。但是我們可以看到,如果你要對一個Apk做盡可能徹底的反編譯,把它扒得乾乾淨淨,這一步一步的基本操作還是稍顯麻煩。另外加固過Apk的情況可能更復雜,需要我們勤動手嘗試。為了能提高效率,下面我把自己見過的一些整合工具介紹給大家,儘可能實現可以一鍵反編譯Apk。

二、自動化工具彙總(一鍵反編譯Apk)

功能:帶有介面,一鍵反編譯Apk工具,直接開啟Apk檔案,就可以看到Apk中所有的檔案結構,甚至還集成了dex檔案檢視,java程式碼檢視,方法數分析、匯入混淆mapping檔案等一系列工具。谷歌推出這個工具的目的是為了讓我們開發者更清楚的瞭解自己的Apk中都有什麼檔案、混淆前後有什麼變化,並方便我們進一步優化自己的Apk打包實現。下面帶上幾張截圖,真是帥氣的一筆的好工具啊!

dex檔案檢視

方法數分析

即將到來的Android Studio 2.2中集成了一個叫做APK Analyzer的功能,這個功能不知道是不是和這個工具有關係呢,本人還沒有嘗試過2.2版本,有興趣的朋友可以體驗一下preview版本

功能:集成了反編譯資源、程式碼等各種檔案的工具包。需要安裝Python環境來執行這個工具,這個工具按照不同的反編譯需求,分別寫成了不同的py功能模組,還有靜態分析的功能。所以如果想要用Python開發一個解析Apk檔案並進行靜態掃描分析的服務,可以引用這個工具來實現。

用法:具體用法比較多,這裡也不再展開了。可以通過工具內建的-h幫助指令檢視各個模組的功能。

1

2

3

4

5

6

7

8

9

10

11

12

unclechendeiMac:androguard-2.0 unclechen$ python androaxml.py -h

Usage: androaxml.py [options]

Options:

-h, --help show this help message and exit

-i INPUT, --input=INPUT

filename input (APK or android's binary xml)

-o OUTPUT, --output=OUTPUT

filename output of the xml

-v, --version version of the API

// androaxml.py這個模組是用來解析AndroidManifest檔案的,`-i` 表示輸入的apk檔案,`-o` 表示輸出xml檔案。

功能:這是網上一位名為Jermic的大神開發的、在Mac環境下使用的App,集成了Android開發中常見的一些編譯/反編譯工具,方便使用者對Apk進行逆向分析,提供Apk資訊檢視功能。工具的截圖如下所示,非常強大。

Android-Crack-Tool.app

功能:在電腦上已經有了這麼多的工具,在手機上的也有很方便的工具。APKParser是一款在檢視手機上已經安裝的Apk的資訊的工具,他可以檢視軟體的AndroidManifest.xml檔案、方法數、res資原始檔,並在手機上直接展示出來。個人覺得這是一個非常實用的工具,作為開發者,手機裡面必須要有它。

ApkParser

5.工具彙總

以上幾款工具都是我體驗過、感覺不錯的整合工具,推薦給大家。臨近本文結束前,又發現了這麼一個福利網站-http://www.androiddevtools.cn/,其中有一章專門總結了各種Apk反編譯的工具。相信有了這麼多的利器,大家應該有100種方法將一個App扒得乾乾淨淨了。

Apk反編譯工具彙總