Android逆向:基礎入門
前言
隨著app的廣泛應用,使用過程中,難免會遇到些很不友好的功能,比如:游戲充值、間斷性彈窗廣告、續費解鎖下一回等等。



如何將這些功能給XX掉?Android逆向就可以做到,縱向絲滑。

當然這只是安卓逆向的非專業性作用之一,安卓逆向的作用不僅限于此,之所以以此引入,是因為激發學習最大的動力——興趣,有了興趣,你們想不學都不行。

網上教程上都這樣講,學習安卓逆向,不可避免的需要掌握一定的java基礎、等等這就話雖說沒錯,但對于零基礎的小白,難道要先學這些編程語言再去入手逆向嗎?
我的想法是,采用理論實踐相結合,邊練邊學,這樣印象才更加深入人心啊

當然此觀念是在經過兩節框架式知識鋪墊的前提下,想了解andorid逆向,沒有提前做功課可不行。接下來這篇文章呢,大家就當科普內容,先了解下andnroid系統的運行機制、框架及andorid應用程序的相關知識。
目錄
- android系統架構
- Dalvik虛擬機與ART虛擬機
- android應用程序架構
- android應用編譯流程
- android應用反編譯流程及工具利用
- android逆向概述
android系統架構
android系統
安卓(Android)是一種基于Linux內核(不包含GNU組件)的自由及開放源代碼的操作系統。主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。

android系統架構

左邊的就是android系統框架了,右邊我加了備注,這樣更加明了,我們可以看到,android系統架構共分四層,從下往上分別是:Linux內核層、系統運行庫層(程序庫+android運行庫)、應用程序框架層、應用層。
大家重點關注下Android Runtime這一部分,其他的簡單了解下就可以涉及到后面的講解:
- Llnux內核層: Android系統是基于Linux內核的,它提供了基本的系統功能及與硬件交互的驅動,像圖中Display Driver(顯示驅動)、Camera Driver(攝像頭驅動)、WiFi Driver(WiFi驅動)等,簡單了解下就可以。
- 系統運行庫層: 像圖中內核的上一層就是系統運行庫層,它由程序庫(綠色部分) 和 Android運行庫(黃色部分) 組成。
- Librares(程序庫): 由C、C++編寫,一系列程序庫的集合,供Android系統的各個組件使用。其中包括:

- Android runtime(Core Librares + Dalvik虛擬機): 翻譯過來就是Android運行時,Android應用程序時采用Java語言編寫,程序在Android運行時中執行,其運行時分為核心庫和Dalvik虛擬機兩部分。
- Dalvik虛擬機(DVM):
- 而 Dalvik虛擬機又是什么鬼?

- 它呢就類似java虛擬機,所有Android應用程序基本是在Dalvik虛擬機環境下運行的。下面會有單獨一章給大家介紹。
- Core Librares(核心庫): 由于DVM也是兼容java語言的,所以Android核心庫,它里面都集成了支持JAVA語言的jar包,
- application Framework(應用程序框架層): 這一層呢主要是提供一些組件,搭建框架,方便app開發人用再次基礎上快速開發開發應用程序。而實際上就是一些AndroidAPI,簡單了解下就可以
- Applications(應用層): 頂層中有所有的 Android 應用程序,如手機中的:電話、文件管理、信息等。

Dalvik虛擬機與ART虛擬機
Dalvik虛擬機
Dalvik是google專門為Android操作系統設計的一個虛擬機,簡稱DVM。在Android 4.4及以前的版本, 所有的Android程序都是在Dalvik虛擬機環境下去運行的。DVM的指令是基于寄存器的,運行的是經過轉換的 .dex文件 (.dex是專為Dalvik設計的一種壓縮格式,適合內存和處理器速度有限的系統),Dalvik虛擬機每次應用運行的時候,將代碼編譯成機器語言執行。
而DVM與JVM的區別:
- JVM運行的是Java字節碼,DM運行的是 Dalvik字節碼。
- 傳統java程序經過編譯,生成java字節碼保存在class文件中,java虛擬機通過解碼class文件來運行程序,而 Dalvik虛擬機運行的是Dalvik字節碼,所有的Dalvik字節碼都由java字節碼轉換而來,并打包到一個dex可執行文件(.dex),Dalvik虛擬機通過解釋DEX文件來執行字節碼。
- DVM是基于寄存器的虛擬機 而JVM執行是基于虛擬棧的虛擬機。
- 寄存器存取速度比棧快的多,dvm可以根據硬件實現最大的優化,比較適合移動設備。
- 以下是同段代碼經反編譯形成的java字節碼與Dalvik字節碼對比
java字節碼

Dalvik字節碼

- dvm執行的是.dex格式文件,jvm執行的是.class文件
- .dex文件,是DVM獨有的執行文件格式,體積更小,速度跟快,占用空間更少
- 運行環境的區別
- Dalvik 經過優化,允許在有限的內存中同時運行多個虛擬機的實例,并且每一個Dalvik 應用作為一個獨立的Linux 進程執行。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關閉。
ART虛擬機
前面說到,當我們使用手機每運行一個程序,Dalvik虛擬機都會產生一個實例,互不影響,這就可能會出現占用資源過多等問題,隨著人們日益增長的需求,dalvik無法滿足人們對軟件運行效率的需要。這是就誕生了ART虛擬機。
在Android4.4及以上版本,應運而生的ART(Android Run Time)虛擬機替代了Dalvik虛擬機,其處理機制根本上的區別是它采用AOT(Ahead of TIme)技術,會在應用程序安裝時就轉換成機器語言,不再在執行時解釋,從而優化了應用運行的速度。在內存管理方面,ART也有比較大的改進,對內存分配和回收都做了算法優化,降低了內存碎片化程度,回收時間也得以縮短。
DVM與ART的區別: 雖說ART替換了Dalvik虛擬機,并不意味著,其應用程序開發上也要發生改變,像android應用程序安裝包(apk)中,仍然還是可執行的.dex文件。
- 執行方式:運行效率提高
- DVM是在每當程序運行時,通過解釋器來執行Davlik字節碼,進而轉化成快速運行的機器碼;而ART是在程序安裝時將字節碼預先編譯成機器碼,這樣運行程序就不用再次編譯
- 預裝時間:增加
- ART安裝程序的時間會長一些,但是每次運行程序會快一點;dvm相反
- 占用存儲空間:增加
- art由于預編譯,所以所占的存儲空間會大一些
- 支持64位 CPU
- DVM是為32位CPU設計的,而ART是支持64位并且兼容32位CPU
Android應用程序架構
安卓應用程序使用JAVA語言編寫。安卓的SDK工具負責將你編寫的代碼,用到的數據和資源文件編譯進APK文件中,APK:android package(應用程序安裝包)。apk文件包含了一個安卓應用程序的所有內容,并且被安卓設備用來安裝應用程序。
而apk實際上就是一個標準的zip格式,修改后綴名,進行解壓就可以看到內部結構


而每個文件夾都有各自不同的作用,大家可以了解下
- assets文件夾: 保存一些額外的資源文件,如游戲的聲音文件,字體文件等等,在代碼中可以用AssetManager獲取assets文件夾的資源。
- lib文件夾: 存放用C/C++編寫的,用NDK編譯生成的so文件,供java端調用。
- META-INF文件夾: 存放apk簽名信息,用來保證apk包的完整性和系統的安全。
- 在IDE編譯生成一個apk包時,會對里面所有的文件做一個校驗計算,并把計算結果存放在META-INF文件夾內,apk在安裝的時候,系統會按照同樣的算法對apk包里面的文件做校驗,如果結果與META-INF里面的值不一樣,系統就不會安裝這個apk,這就保證了apk包里的文件不能被隨意替換。比如拿到一個apk包后,如果想要替換里面的一幅圖片,一段代碼, 或一段版權信息,想直接解壓縮、替換再重新打包,基本是不可能的。如此一來就給病毒感染和惡意修改增加了難度,有助于保護系 統的安全。
- res文件夾: 存放資源文件,包括icon,xml文件
- res/layout/: 存放被編譯為屏幕布局(或屏幕的一部分)的XML文件
- res/values/: 存放可以被編譯成很多類型的資源文件
- array.xml: 定義數組
- string.xml: 定義字符串(string)值
- AndroidManifest.xml文件: 應用程序配置文件,每個應用都必須定義和包含的,它描述了應用的名字、版本、權限、引用的庫文件等信息。
- classes.dex文件: 傳統 Class 文件是由一個 Java 源碼文件生成的 .Class 文件,而 Android 是把所有 Class 文件進行合并優化,然后生成一個最終的 class.dex 文件。它包含 APK 的可執行代碼,是分析 Android 軟件時最常見的目標。由于dex文件很難看懂,可通過apktool反編譯得到.smali文件,smali文件是對Dalvik虛擬機字節碼的一種解釋(也可以說是翻譯),并非一種官方標準語言。通過對smali文件的解讀可以獲取源碼的信息。
- resources.arsc文件: 二進制資源文件,包括字符串等。
- smali: smali是將Android字節碼用可閱讀的字符串形式表現出來的一種語言,可以稱之為Android字節碼的反匯編語言。利用apktool或者Android Killer,反編classes.dex文件,就可以得到以smali為后綴的文件,這些smali文件就是Dalvik的寄存器語言。
Android應用編譯流程

Android應用編譯流程按圖中的例子就是一個app應用的生成過程。在應用程序上架的時候都需要程序經過編譯、簽名 、生成一個后綴為apk的文件才能發布到應用市場。
下面給大家簡單講解下:
- 第一步:打包資源文件,生成R.java文件
- 通過利用aapt資源打包工具,將文件目錄中的Resource文件(就是工程中res中的文件)、Assets文件、AndroidManifest.xml文件、Android基礎類庫(Android.jar文件)進行打包,生成R.java
- 第二步:aidl生成Java文件
- AIDL是Android Interface Definition Language的簡稱, 是Android跨進程通訊的一種方式。檢索工程里所有的aidl文件,并轉換為對應的Java文件
- 第三步:編譯Java文件,生成對應的.class文件
- 將R.java、aidl生成的Java文件、Java源文件通過JDK攜帶的Javac編譯生成.class文件
- 第四步:把.class文件轉化成Davik VM支持的.dex文件
- 通過dx工具將.class文件生成為classes.dex
- 第五步:打包生成未簽名的.apk文件
- 利用apkbuilder工具,將resources.arsc、res目錄、AndroidManifest.xml、assets目錄、dex文件打包成未簽名的apk
- 第六步:對未簽名.apk文件進行簽名
- 使用apksigner為安裝包添加簽名信息。
- 第七步:對簽名后的.apk文件進行對齊處理
- 使用zipalign工具對簽名包進行內存對齊操作, 即優化安裝包的結構。
Android應用反編譯流程及工具利用

而Android應用反編譯流程就是上面所講的app生成過程的逆過程。Android應用程序的反編譯,算是我們入手Android逆向展開實踐的第一步。
下面給大家簡單講解下流程:
首先可以看到最左邊的目標unsigned apk,即未簽名apk。整體可以看出有兩條反編譯路線。
反編譯方式一: 圖中上面這條路線是通過利用apktool這款工具,可直接對目標apk直接進行反編譯,可以看到除apk本身的資源文件,還生成了smali文件,而smali文件里面包含的都是程序執行的核心代碼。我們可以通過直接分析.smali文件中的smali代碼,進而修改代碼,改變其運行邏輯。
apktool工具下載地址:
https://bitbucket.org/iBotPeaches/apktool/downloads/
利用方式: cmd運行命令
apktool d target.apk

反編譯完成后會生成文件夾

反編譯方式二: 圖中下面這條路線是通過修改apk后綴名,對其解壓后,將文件夾中的資源文件,通過利用AXMLPrinter2進行分析,進而反編譯,而對于解壓后的class.dex文件,利用Dex2jar反編譯工具對其進行反編譯得到jar文件。接著將生成的jar文件直接拖到JD-GUI文件中,可自動生成源碼,我們可通過分析其源碼,了解其程序的運行邏輯,但我們修改邏輯,最終還是需要在smali文件中進行修改。
dex2jar下載地址: https://sourceforge.net/projects/dex2jar/files/
利用方式: cmd運行命令
dex2jar.bat classes.dex

目錄生成新的jar

而jd-gui反編譯工具的使用方法,可直接將jar文件拖到工具中,會自動進行反編譯出源碼進行查看

jd-gui下載地址:http://java-decompiler.github.io/
工具推薦
以上就是傳統的Android反編譯流程,若想具體了解過程,可通過上述流程進行自我復現。
而在Android逆向的實際應用中,個人比較推薦Android killer 與 jadx-gui這兩款工具
- Android killer: 是集Apk反編譯、Apk打包、Apk簽名,編碼互轉,ADB通信(應用安裝-卸載-運行-設備文件管理)、源碼查看等特色功能于一身,支持logcat日志輸出,語法高亮,基于關鍵字(支持單行代碼或多行代碼段)項目內搜索,可自定義外部工具;吸收融匯多種工具功能與特點,是一款可視化的安卓應用逆向工具。
- 可以說在Android逆向,這款工具可實現上述反編譯流程一把梭,這大大節省了操作時間,也提高了我們的效率。

AndroidKiller下載地址:https://down.52pojie.cn/Tools/Android_Tools/AndroidKiller_v1.3.1.zip
- jadx-gui: 是一款可以將apk,dex,aar 和 zip 文件將 Dalvik 字節碼反編譯為 Java 類的JAVA反編譯工具。
- 而它是支持apk、dex、aar、zip等格式,所以我們在使用過程中,可直接將待測apk拖入的工具中,會自動執行反編譯

jadx-gui下載地址:https://down.52pojie.cn/Tools/Android_Tools/jadx_v1.3.4.zip
Android逆向概述
ok,基本的知識框架體系已經啰嗦完了,現在開始我們的重點——Android逆向。
什么是Android逆向呢?
官方話語: Android逆向是對已經打包好的APP進行反編譯、源碼分析了解APP實現邏輯的一門技術。
通俗理解呢: 就是玩具(app)經過零件組裝(源碼編譯)、加工刷漆(打包、簽名)生成成品的逆過程。我們把成品的app,再將它打回零件形態——源碼,通過更改它的零件(代碼),再進行重組裝(重編譯),使它可以飛天、遁地等等(改變運行邏輯)
當然,這里的更改零件,指的可不是app的源碼,而是經反編譯后的smali代碼。
而在實際應用中,我們逆向的話,需要用到解密、反編譯、解壓縮等技術,想要100%還原APK的源碼幾乎是不可能的,所以在實際進行逆向分析的時候,一般都是根據想實現的目的,分析出APK的部分源碼和實現邏輯,然后對這一部分源碼進行修改后與原始的APK打包在一起,這樣就獲得了一個實現自己特定目的的APP。
總結與思考
以上文章就介紹的到這里,讀到這里可能你們都覺得本篇涉及逆向的知識點并不多,而我也說過,了解Android逆向,要先了解Android,之所以這樣說呢,是因為Android逆向的學習,最終還是要歸到Android本身,有了前面的了解,相信會對接下來Android逆向分析上有著很大幫助。
后面要講的就是逆向分析的手段以及具體流程,實踐與理論結合的邊練邊學了,大家可以自己針對Android應用程序的反編譯流程操練一番,備好工具,下一篇開搞。