天天看點

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

哔哩哔哩:https://www.bilibili.com/video/BV1UE411A7rW?p=1

Android 逆向工程師系統教育訓練‹第九期›( 課程目錄 ):https://ke.yijincc.com/course-21.htm

安卓逆向工程師:https://ke.yijincc.com/profession/1.htm

打造年輕人的第一套安卓逆向環境!

原味鏡像介紹文章:https://mp.weixin.qq.com/s/gBdcaAx8EInRXPUGeJ5ljQ

原味鏡像介紹視訊:https://www.bilibili.com/video/BV1qQ4y1R7wW/

下載下傳位址:

谷歌盤:https://drive.google.com/drive/folders/1AdZ1x5G9CcJGXiLqGL9mhDJWlRz8KZl_?usp=sharing

GoFile:https://gofile.io/d/GeqM2O

百度盤:連結:https://pan.baidu.com/s/1anvG0Ol_qICt8u7q5_eQJw 提取碼:3x2a

阿裡盤:http://49.235.84.125:8080/r0env

登入時使用者名:root 密碼:toor

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

1. 逆向環境配置

1. java 開發環境:java jdk、java jre

        java jdk 最好安裝 jdk8 的最新版本,如果安裝更高的 java 版本,一些逆向工具可能使用不了。

        安裝 java jdk8 的時候會自動彈出 對應 jre 的安裝。

2. 安卓開發環境:安卓 sdk、ndk

        安卓 sdk 和 ndk 下載下傳完成後,直接解壓,然後配置環境變量即可。。。

        也可以通過 android studio 進行 sdk 和 ndk 的安裝

        通過 Android studio下載下傳的 sdk 中沒有 tools 檔案夾的解決辦法:

                https://blog.csdn.net/General_Ma/article/details/104707265/

        sdk 主要配置兩個目錄:tools、platform_tools

        ndk 的安裝:官網下載下傳 ( https://developer.android.google.cn/ndk/ )  ndk 進行安裝

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

2. APK 檔案結構

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

APK 是 Android PacKage 的縮寫,即 Android 安裝包。apk 檔案也就是 Android 打包流程的産物。那麼 apk 是一個什麼類型的檔案?它包含了一些什麼内容? 弄清楚了這些,我們就可以帶着目的性,去分析打包流程,可以更好的關注 apk 檔案中的這些内容是在打包流程的哪個過程中産生,以及是如何産生的。

衆所周知,apk 檔案本質上其實是一個 zip 格式的壓縮包。想要知道其中包含了什麼,改字尾然後用解壓縮工具即可打開任何一個APK檔案。 如果有 代碼混淆 和 加密,通過普通解壓縮工具打開裡面的檔案或目錄會看到各種亂碼。

apk 概覽

  • assets (程式資源目錄)
  • META-INF(簽名證書目錄)
  • res(界面布局/圖檔資源目錄)
  • AndroidManifest.xml(APK屬性/權限/元件聲明)
  • classes.dex(Android 虛拟機可執行位元組碼)
  • resources.arsc(字元串/資源索引檔案)

圖示:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

這裡解壓了某個未經過 加強加殼 或者 其他手段加密的 Android 安裝封包件,以下為結果截圖:

https://www.sohu.com/a/149758866_675634

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

主要注意紅色标注部分,這一些檔案和檔案夾是一個 Android 應用基本都具備的。而其他的一些檔案和檔案夾則是一些第三方庫,或者是其他一些代碼生成的。 接下來,依次大概介紹一下這些檔案和檔案夾的作用。

  • AndroidManifest.xml:這是 Android 應用的全局配置檔案,它包含了這個應用的很多配置資訊,例如包名、版本号、所需權限、注冊的服務等。可以根據這個檔案在相當程度上了解這個應用的一些資訊。該檔案目前狀态是被編譯為二進制的 XML 檔案,可以通過一些工具(如 apktool)反編譯後進行檢視。Analyze apk 是一個很不錯的 apk 分析(~~hack 入門~~)工具。我們可以通過它直接反編譯看到原始的 AndroidManifest.xml 檔案。
    安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機
  • assets 檔案夾:assets 檔案夾用于儲存需要保持原始檔案的資源檔案夾,開發過程中拖了什麼到裡面,打包完之後裡面還是什麼。一般用于存放音頻,網頁(幫助頁面之類的),字型等檔案。主要需要知道的點是,它與 res 檔案夾的區分以及如何在應用中通路該檔案夾的資源,如它可以有多級目錄而 res 則隻有兩級。
    安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機
  • dex 檔案:classes.dex 檔案是 Android 系統運作于 Dalvik Virtual Machine 上的可執行檔案,也是Android 應用程式的核心所在。項目工程中的 Java 源碼通過 javac 生成 class 檔案,再通過 dx 工具轉換為 classes.dex,注意到我們這裡有 classes2.dex 和 classes3.dex。這是方法數超過一個 dex 的上限,分 dex 的結果。分 dex 在 Android 5.0 之前需要開發者自行完成,5.0 後 dx 自帶支援。dex 檔案的資料結構不算複雜,如下圖所示。目前一些熱更新檔有關的技術,主要便是對 dex 做各種處理。
  • lib 檔案夾:該目錄存放着應用需要的 native 庫檔案。比如一些底層實作的圖檔處理、音視訊處理、資料加密的庫以 so 庫的形式在該檔案夾中。而該檔案夾下有時會多一個層級,這是根據不同CPU 型号而劃分的,如 ARM,ARM-v7a,x86等。
    安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機
  • META-INF 檔案夾:該目錄的主要作用是用于保證 APK 的完整性以及安全性。該檔案夾下,主要有三個檔案。

            MANIFEST.MF:這個檔案儲存了 整個apk檔案 中 所有檔案的檔案名 + SHA-1後的編碼值。

                                        這也就意味着,MANIFEST.MF 象征着 apk 包的完整性。

            XXX.RSA:這個檔案儲存了公鑰和加密方式的資訊。

            XXX.SF:這個檔案與 MANIFEST.MF 的結構一樣,隻是其編碼會被被私鑰加密。

                               這樣一來每次安裝時,通過該檔案夾中的檔案,就可以完成驗證的過程。

                               如果 apk 包被改變了,而篡改者沒有私鑰生成 CERT.SF,則無法完成校驗。

    安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機
  • res 檔案夾:顧名思義,該檔案夾是資源檔案夾。它裡面存放的所有檔案都會被映射到 R 檔案中,生成對應的資源 ID,便于代碼中通過 ID 直接通路。其中的資源檔案包括了動畫(anim),圖像(drwable),布局(layout),常量值(values),顔色值(colors),尺寸值(dimens),字元串(strings),自定義樣式(styles)等。
  • resource.arsc 檔案:這個檔案可以說是所有檔案中結構最複雜的。它記錄了資源檔案,資源檔案位置(各個次元的路徑)和資源 id 的映射關系。并且将所有的 string 都存放在了 string pool 中,節省了在查找資源時,字元串處理的開銷。

    我們可以使用 Androdi Studio 2.2 Preview 中的新功能 Analyze apk (這個新功能用來分析 apk 非常好用,強烈推薦各位讀者可以嘗試一下)來看看它到底包含了些什麼,一圖勝過千言:

    安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

    可以看到,首先是有個 package 可選,實際上 resource.arsc 是可以包含多個 package 的資源的。 然後可以看到一個 Resource Types 的清單。這裡看到的是 drawable 的 type。 右邊顯示了有多少個 drawable 以及多少項 configurations,以及表的具體内容為 ID - Name - 各個次元的值(在這裡即是資源的路徑),通過這個,我們可以完成通過 id + 對應的 configuration 擷取對應資源的操作。

    而後面要提到資源混淆的原理,就是修改這裡各個次元的值,并修改對應 res 裡面的檔案夾以及檔案名實作的。

    具體其完整的資料結構比較複雜,在這裡就不展開說了,有興趣的讀者可以自行查閱資訊,甚至寫一個 parser 出來也是非常有意思的。

總結:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

3. APK 打包流程

android配置建構 官方文檔

Android應用程式(APK)的編譯打包過程:https://www.cnblogs.com/sjm19910902/p/6416022.html

Android APK打包流程:https://www.cnblogs.com/xunbu7/p/7345912.html

APK打包流程:https://blog.csdn.net/loongago/article/details/89646920

apk檔案以及打包流程:https://blog.csdn.net/mysimplelove/article/details/93516904

淺述Android Apk打包流程:https://www.jianshu.com/p/d29c37dda256

Android 打包之流程:https://www.jianshu.com/p/d22f52a6a6fb

APK打包安裝過程:https://segmentfault.com/a/1190000004916563

原創]記一次APP脫殼重打包過程:https://bbs.pediy.com/thread-220151.htm

下圖的是官網對于Android編譯打包流程的介紹。

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

官方的介紹非常籠統,簡而言之,其大緻流程就是: 編譯–>DEX–>打包–>簽名和對齊

來一張外國大神的圖檔(注:這張圖少了簽名的步驟)

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

流程圖:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

重點關心的是

  • (1)這個過程的輸入是什麼?
  • (2)這個過程的輸出是什麼?
  • (3)這個過程使用了什麼工具?至于使用什麼參數,可以自己去看對應指令的幫助檔案,或者在網上搜尋,

aapt -> aidl -> javac -> dx(dex) -> apkbuilder -> jarsigner -> zipalign

步驟中提到的工具如下表:

名稱 功能介紹 在作業系統中的路徑
aapt Android 資源打包工具 ${ANDROID_SDK_HOME}/platform-tools/appt
aidl

Android接口描述語言轉化為.java檔案的工具

( aidl 全名 Android Interface Definition Language,即Android接口定義語言 )

${ANDROID_SDK_HOME}/platform-tools/aidl
javac Java Compiler ${JDK_HOME}/javac或/usr/bin/javac
dex 轉化.class檔案為Davik VM能識别的.dex檔案 ${ANDROID_SDK_HOME}/platform-tools/dx
apkbuilder 生成 apk 包 (SDK3.0 之後棄用,而使用 sdklib.jar 打包 apk) ${ANDROID_SDK_HOME}/tools/opkbuilder
jarsigner .jar檔案的簽名工具 ${JDK_HOME}/jarsigner或/usr/bin/jarsigner
zipalign 位元組碼對齊工具 ${ANDROID_SDK_HOME}/tools/zipalign

補充:apkbuilder 在 SDK3.0 之前使用 apkbuilder 去打包,在 SDK3.0 之後就棄用了,而使用 sdklib.jar 打包 apk。

下面各個工具在打包中的用法:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

編譯打包步驟:

  • 1. 打包資源檔案,生成R.java檔案。打包資源的工具是aapt(The Android Asset Packaing Tool)(E:\Documents\Android\sdk\build-tools\25.0.0\aapt.exe)。在這個過程中,項目中的AndroidManifest.xml檔案和布局檔案XML都會編譯,然後生成相應的R.java,另外AndroidManifest.xml會被aapt編譯成二進制。存放在APP的res目錄下的資源,該類資源在APP打包前大多會被編譯,變成二進制檔案,并會為每個該類檔案賦予一個resource id。對于該類資源的通路,應用層代碼則是通過resource id進行通路的。Android應用在編譯過程中aapt工具會對資源檔案進行編譯,并生成一個resource.arsc檔案,resource.arsc檔案相當于一個檔案索引表,記錄了很多跟資源相關的資訊。
  • 2. 處理aidl檔案,生成相應的Java檔案。這一過程中使用到的工具是aidl(Android Interface Definition Language),即Android接口描述語言(E:\Documents\Android\sdk\build-tools\25.0.0\aidl.exe)。aidl工具解析接口定義檔案然後生成相應的Java代碼接口供程式調用。如果在項目沒有使用到aidl檔案,則可以跳過這一步。
  • 3. 編譯項目源代碼,生成class檔案。項目中所有的Java代碼,包括R.java和.aidl檔案,都會變Java編譯器(javac)編譯成.class檔案,生成的class檔案位于工程中的bin/classes目錄下。
  • 4. 轉換所有的class檔案,生成classes.dex檔案。dx工具生成可供Android系統Dalvik虛拟機執行的classes.dex檔案,該工具位于(E:\Documents\Android\sdk\build-tools\25.0.0\dx.bat)。任何第三方的libraries和.class檔案都會被轉換成.dex檔案。dx工具的主要工作是将Java位元組碼轉成成Dalvik位元組碼、壓縮常量池、消除備援資訊等。
  • 5. 打包生成APK檔案。所有沒有編譯的資源,如images、assets目錄下資源(該類檔案是一些原始檔案,APP打包時并不會對其進行編譯,而是直接打包到APP中,對于這一類資源檔案的通路,應用層代碼需要通過檔案名對其進行通路);編譯過的資源和.dex檔案都會被apkbuilder工具打包到最終的.apk檔案中。打包的工具apkbuilder位于 android-sdk/tools目錄下。apkbuilder為一個腳本檔案,實際調用的是(E:\Documents\Android\sdk\tools\lib)檔案中的com.android.sdklib.build.ApkbuilderMain類。
  • 6. 對APK檔案進行簽名。一旦APK檔案生成,它必須被簽名才能被安裝在裝置上。在開發過程中,主要用到的就是兩種簽名的keystore。一種是用于調試的debug.keystore,它主要用于調試,在Eclipse或者Android Studio中直接run以後跑在手機上的就是使用的debug.keystore。另一種就是用于釋出正式版本的keystore。
  • 7. 對簽名後的APK檔案進行對齊處理。如果你釋出的 apk 是正式版的話,就必須對APK進行對齊處理,用到的工具是zipalign(E:\Documents\Android\sdk\build-tools\25.0.0\zipalign.exe)。對齊的主要過程是将APK包中所有的資源檔案距離檔案起始偏移為4位元組整數倍,這樣通過記憶體映射通路apk檔案時的速度會更快。對齊的作用就是減少運作時記憶體的使用。

上述流程都是Android Studio在編譯時調用各種

編譯指令

自動完成的

第一步:打包資源檔案,生成R.java檔案

編譯 R.java 類 需要用到 AndroidSDK 提供的 aapt 工具,aapt 參數衆多,以下是主要參數:

-d  one or more device assets to include, separated by commas  
 -f  force overwrite of existing files  
 -g  specify a pixel tolerance to force images to grayscale, default 0  
 -j  specify a jar or zip file containing classes to include  
 -k  junk path of file(s) added  
 -m  make package directories under location specified by -J  
 -u  update existing packages (add new, replace older, remove deleted files)  
 -v  verbose output  
 -x  create extending (non-application) resource IDs  
 -z  require localization of resource attributes marked with  
     localization="suggested"  
 -A  additional directory in which to find raw asset files  
 -G  A file to output proguard options into.  
 -F  specify the apk file to output  
 -I  add an existing package to base include set  
 -J  specify where to output R.java resource constant definitions  
 -M  specify full path to AndroidManifest.xml to include in zip  
 -P  specify where to output public resource definitions  
 -S  directory in which to find resources.  Multiple directories will be scann  
           

aapt 編譯 R.java 檔案具體如下:

需要進入應用程式目錄,建立一個gen目錄,沒有gen目錄,指令将會出現找不到檔案的錯誤!

指令成功執行後将會在 gen 目錄下生成成包結構的目錄樹,及 R.java 檔案。

列子:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

aapt 資源編譯

  1. 編譯assets目錄和res/raw目錄下的資源
  2. 編譯res目錄下的資源檔案
  3. 給res目錄下的每個資源賦予一個資源ID,生成resource.arsc資源索引檔案
  4. 解析并編譯AndroidMainifest.xml
  5. 資源打包成*.ap_,資源ID常量定義自R.java

資源索引

aapt 給每一個非 assets 目錄的資源定義一個資源ID,它是一個4位元組(byte = 32bit)的數字,格式是PPTTNNNN,PP代表資源所屬的包(package),TT代表資源的類型(Type),NNNN代表這個類型下面的資源名稱(Entry ID)。

  • Package ID相當于是一個命名空間,标定資源的來源。系統資源的命名空間,它的package ID等于0x01;自己的APP資源名稱空間,Package ID一般定義為0x7f。
  • Type ID是指資源的類型ID。資源的類型都有animator、anim、color、drawable、layout、menu、raw、string和xml等等若幹種,每一種都會被賦予一個ID。
  • Entry ID是指每一個資源在其所屬的資源類型中所出現的次序。

代碼編譯和打包

  • AIDL -> 生成對應的java接口
  • Javac -> 生成.class檔案
  • dex-> 生成dex檔案
  • APkBuilder:aapt打包好的資源、dex打包好的代碼檔案、第三方庫資源和jar檔案、native -> apk

第二步:處理AIDL檔案,生成對應的.java檔案

(當然,有很多工程沒有用到AIDL,那這個過程就可以省了)

将 .aidl 檔案生成 .java 檔案需要用到 AndroidSDK 自帶的 aidl 工具,此工具具體參數如下:

-I<DIR>    search path for import statements.  
-d<FILE>   generate dependency file.  
-p<FILE>   file created by --preprocess to import.  
-o<FOLDER> base output folder for generated files.  
-b         fail when trying to compile a parcelable.  
值得注意的是:這個工具的參數與參數值之間不能有空格,Google也有對工資不滿意的工程師! 
           

例子:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

第三步:編譯Java檔案,生成對應的.class檔案

javac 指令用法如下:

其中,可能的選項包括:  
  -g                         生成所有調試資訊  
  -g:none                    不生成任何調試資訊  
  -g:{lines,vars,source}     隻生成某些調試資訊  
  -nowarn                    不生成任何警告  
  -verbose                   輸出有關編譯器正在執行的操作的消息  
  -deprecation               輸出使用已過時的 API 的源位置  
  -classpath <路徑>            指定查找使用者類檔案和注釋處理程式的位置  
  -cp <路徑>                   指定查找使用者類檔案和注釋處理程式的位置  
  -sourcepath <路徑>           指定查找輸入源檔案的位置  
  -bootclasspath <路徑>        覆寫引導類檔案的位置  
  -extdirs <目錄>              覆寫安裝的擴充目錄的位置  
  -endorseddirs <目錄>         覆寫簽名的标準路徑的位置  
  -proc:{none,only}          控制是否執行注釋處理和/或編譯。  
  -processor <class1>[,<class2>,<class3>...]要運作的注釋處理程式的名稱;繞過預設的搜尋程序  
  -processorpath <路徑>        指定查找注釋處理程式的位置  
  -d <目錄>                    指定存放生成的類檔案的位置  
  -s <目錄>                    指定存放生成的源檔案的位置  
  -implicit:{none,class}     指定是否為隐式引用檔案生成類檔案  
  -encoding <編碼>             指定源檔案使用的字元編碼  
  -source <版本>               提供與指定版本的源相容性  
  -target <版本>               生成特定 VM 版本的類檔案  
  -version                   版本資訊  
  -help                      輸出标準選項的提要  
  -Akey[=value]              傳遞給注釋處理程式的選項  
  -X                         輸出非标準選項的提要  
  -J<标志>                     直接将 <标志> 傳遞給運作時系統  
           

例子:

javac -encoding utf-8 -target 1.5 -bootclasspath E:\Androiddev\android-sdk-windows2.2\platforms\android-3\android.jar -d bin src\com\byread\reader\*.java gen\com\byread\reader\R.java 

第四步:把.class檔案轉化成Davik VM支援的.dex檔案

将工程 bin目錄下的 class 檔案編譯成 classes.dex,Android 虛拟機隻能執行 dex 檔案。

例子:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

第五步:打包生成未簽名的 .apk 檔案

  • 【輸入】打包後的資源檔案、打包後類檔案(.dex檔案)、libs檔案(包括.so檔案,當然很多工程都沒有這樣的檔案,如果你不使用C/C++開發的話)
  • 【輸出】未簽名的.apk檔案
  • 【工具】apkbuilder工具

apkbuilder  工具用法如下:

-v      Verbose.  
-d      Debug Mode: Includes debug files in the APK file.  
-u      Creates an unsigned package.  
-storetype Forces the KeyStore type. If ommited the default is used.  
   
-z      Followed by the path to a zip archive.  
        Adds the content of the application package.  
   
-f      Followed by the path to a file.  
        Adds the file to the application package.  
   
-rf     Followed by the path to a source folder.  
        Adds the java resources found in that folder to the application  
        package, while keeping their path relative to the source folder.  
   
-rj     Followed by the path to a jar file or a folder containing  
        jar files.  
        Adds the java resources found in the jar file(s) to the application  
        package.  
   
-nf     Followed by the root folder containing native libraries to  
        include in the application package.
           

列子:

apkbuilder  ${output.apk.file} -u -z  ${packagedresource.file} -f  ${dex.file}  -rf  ${source.dir}  -rj  ${libraries.dir} 

第六步:對未簽名 .apk 檔案進行簽名

通過 jarsigner 指令用證書檔案對未簽名的 APK 檔案進行簽名

【輸入】未簽名的.apk檔案

【輸出】簽名的.apk檔案

【工具】jarsigner

用法:jarsigner [選項] jar 檔案别名  
       jarsigner -verify [選項] jar 檔案  
  
[-keystore <url>]           密鑰庫位置    
[-storepass <密碼>]         用于密鑰庫完整性的密碼    
[-storetype <類型>]         密鑰庫類型    
[-keypass <密碼>]           專用密鑰的密碼(如果不同)    
[-sigfile <檔案>]           .SF/.DSA 檔案的名稱    
[-signedjar <檔案>]         已簽名的 JAR 檔案的名稱    
[-digestalg <算法>]    摘要算法的名稱    
[-sigalg <算法>]       簽名算法的名稱    
[-verify]                   驗證已簽名的 JAR 檔案    
[-verbose]                  簽名/驗證時輸出詳細資訊    
[-certs]                    輸出詳細資訊和驗證時顯示證書    
[-tsa <url>]                時間戳機構的位置    
[-tsacert <别名>]           時間戳機構的公共密鑰證書    
[-altsigner <類>]           替代的簽名機制的類名    
[-altsignerpath <路徑清單>] 替代的簽名機制的位置    
[-internalsf]               在簽名塊内包含 .SF 檔案    
[-sectionsonly]             不計算整個清單的散列    
[-protected]                密鑰庫已保護驗證路徑    
[-providerName <名稱>]      提供者名稱    
[-providerClass <類>        加密服務提供者的名稱  
[-providerArg <參數>]] ... 主類檔案和構造函數參數  
           

隻需要按步驟生成 MANIFEST.MF, CERT.RSA,CERT.SF 并放入META-INF 檔案夾即可。

第七步:對簽名後的.apk檔案進行對齊處理

(不進行對齊處理是不能釋出到Google Market的)

【輸入】簽名後的.apk檔案

【輸出】對齊後的.apk檔案

【工具】zipalign工具

知道了這些細節之後,我們就可以實作很多我們想實作東西了,比如:自動化,我們可以使用某種腳本,像Windows下的批處理,linux下的Bash,Java下的Ant,Python、Perl這樣的腳本語言,甚至直接用Java、.net這們的強類型語言也是可以的。

以上便是APK打包的整個流程,我們再來總結一下:

  • 除了assets和res/raw資源被原裝不動地打包進APK之外,其它的資源都會被編譯或者處理;
  • 除了assets資源之外,其它的資源都會被賦予一個資源ID;
  • 打包工具負責編譯和打包資源,編譯完成之後,會生成一個resources.arsc檔案和一個R.java,前者儲存的是一個資源索引表,後者定義了各個資源ID常量。
  • 應用程式配置檔案AndroidManifest.xml同樣會被編譯成二進制的XML檔案,然後再打包到APK裡面去。
  • 應用程式在運作時通過AssetManager來通路資源,或通過資源ID來通路,或通過檔案名來通路。

4. APK 安裝流程

Android中APK安裝流程解析:https://blog.csdn.net/mysimplelove/article/details/93619361

APK安裝後最終放置在了哪裡?安裝APP到底是怎樣的一個過程?如何打開并修改APK程式包?

如果使用 WinHex 打開apk檔案,從檔案頭就可以看出APK安裝包其實就是一個zip格式的壓縮包,是以我們隻需将apk檔案的字尾修改為 .zip 或 .rar ,就可以輕松的在電腦上打開并檢視apk軟體内部的檔案和資料(當然你也可以使用手機R.E管理器檢視)。

Android 安裝 apk包的五種方式:

  • 1, 通過工具安裝:R.P 或 ES等管理工具,有安裝界面。
  • 2,adb install 安裝,無安裝界面。
  • 3,android market 線上安裝,無安裝界面。
  • 4,直接 copy 到系統目錄/system/app下,無安裝界面。此目錄下的應用一般是系統自帶的系統級程式和常歸應用。
  • 5,pm(android 系統自帶工具) 指令行安裝,無安裝界面。

apk 檔案在安裝到手機過程中,涉及到如下幾個目錄:

/system/framwork:    儲存的是資源型的應用程式,它們用來打包資源檔案。
/data/app-private:   儲存受DRM保護的私有應用程式。
/vendor/app:         儲存裝置廠商提供的應用程式。
/system/app           ------- 系統自帶的應用安裝目錄,獲得 adb root權限才能删除
/data/app             ------- 使用者程式安裝的目錄,安裝時把 apk檔案 複制到 此目錄
/data/data            ------- 存放應用程式的資料
/data/dalvik-cache    将 apk 中的 dex檔案 安裝到 dalvik-cache 目錄下
                     (dex檔案是dalvik虛拟機的可執行檔案,其大小約為原始apk檔案大小的四分之一)

/data/system:該目錄下的packages.xml檔案,類似于Windows的系統資料庫,記錄了系統的permissions,
            每個apk的name,codePath,,version,userid等資訊,這些資訊主要通過AndroidManifest.xml
            檔案解析擷取,解析完apk後将更新資訊寫入這個檔案并儲存到flash,下次開機的時候直接從裡
            面讀取相關資訊并添加到記憶體相關清單中。當有APK安裝、更新或者删除時會更新這個檔案。

/data/system/packages.xml /data/system/packages.list: 
        packages.list指定了應用的預設存儲位置/data/data/com.xxx.xxx;package.xml中包含了該應用 
        權限、應用包名、APK的安裝位置、版本、userID等資訊,并且兩者都有同一個userld。之是以每個 
        應用都要一個userId,是因為Android在系統設計上把每個應用當做Linux系統上的一個使用者對待, 
        這樣就可以利用已有的Linux使用者管理機制來設計Android應用,
        比如應用目錄,應用權限,應用程序管理等。


           

安裝過程:

當我們新安裝一個應用的時候,通常系統會執行以下流程:

校驗apk包簽名 → 複制程式包到 /data/app 目錄 → 建立 /data/data/com.xxx 資料目錄 → 提取釋放lib檔案 → dexopt優化classes.dex處理後釋放到 /data/dalvik-cache 目錄

在這個過程中,Android 系統服務還會更新以下系統檔案:

  • /data/system/packages.list   --  配置設定存儲APP的uid/gid,也就是使用者/所屬組
  • /data/system/packages.xml  --  記錄儲存APP權限、簽名證書、安裝路徑、版本資訊等

由此可見,我們安裝好的軟體程式包被原本不動存放在 /data/app 目錄之下,資料目錄則被安放在 /data/data/pkg_name(包名) 目錄之中。而解除安裝過程則相反,進行删除相關檔案處理。

整個 apk 安裝流程:

  • 複制 APK 到 /data/app 目錄 下,解壓(會放到 data/app/包名/ 目錄下面,同時 apk 中的 so 檔案 也會拷貝到此目錄下的 lib 檔案目錄中。)并掃描安裝包。而系統出廠的 apk 被放到 /system分區下,這就是沒有ROOT手機前,我們無法删除系統app的原因。( 下面 是用 MT 管理器 (需要擷取root 權限) 打開)
    安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機
  • 資料總管解析 APK 裡的資源檔案。
  • 解析 AndroidManifest.xml(Android應用程式的解析過程就是解析這個xml檔案的過程)。解析的内容會被更新到

    /data/system/packages.xml 

    和 

    /data/system/packages.list

    中,packages.list 中指名了該應用預設存儲的位置,packages.xml 中包含了該應用申請的權限、簽名和代碼所在位置等資訊,并且兩者都有一個 相同的 userId。之是以每個應用都有一個userId,是因為Android 在系統設計上把每個應用當作Linux系統上的一個使用者對待,這樣就可以利用已有的Linux上使用者管理機制來設計Android應用,比如應用目錄,應用權限,應用程序管理等。做完以上操作,就相當于應用在系統注冊了,可以被系統識别。接下來就得儲存應用的執行檔案了,根據 

    packages.xml

    中指定的 

    codePath

    ,建立一個目錄,即在 /data/data/ 目錄 下建立對應的 應用資料目錄。apk會被命名成 

    base.apk 

    并拷貝到此,其中 lib 目錄用來存放 native 庫
  • 然後對 dex 檔案進行優化,并儲存在 dalvik-cache目錄 下。其命名規則是 apk路徑+classes.dex。(此時應用就可以運作了,但如果每次應用運作還得去base.apk中取dex檔案,效率就太低了。為了提升效率,Android系統在應用安裝時還會做些優化操作,把所有可運作的dex檔案單獨提取放在一塊并做些優化。在Dalvik模式下,會使用dexopt把base.apk中的dex檔案優化為odex,存儲在

    /data/dalvik-cache

    中,如果是ART模式,則會使用dex2oat優化成oat檔案也存儲在該目錄下,并且檔案名一樣,但檔案大小會大很多,因為ART模式會在安裝時把dex優化為機器碼,是以在ART模式下的應用運作更快,但apk安裝速度相對Dalvik模式下變慢,并且會占用更多的ROM。)
  • 将 AndroidManifest 檔案解析出的四大元件資訊注冊到 PackageManagerService 中。
  • 安裝完成後,發送廣播。
  • 顯示icon圖示:應用程式經過PMS中的邏輯處理後,相當于已經注冊好了,如果想要在Android桌面上看到icon圖示,則需要Launcher将系統中已經安裝的程式展現在桌面上。

安裝圖解和過程描述:

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機

安裝過程并沒有把資源檔案, assets目錄下檔案拷貝出來,他們還在apk包裡面呆着,是以,當應用要通路資源的時候,其實是從apk包裡讀取出來的。其過程是,首先加載apk裡的resources.arsc(這個檔案是存儲資源Id與值的映射檔案),根據資源id讀取加載相應的資源。

删除安裝過程:就是删除在上述三個目錄下建立的檔案及目錄。

總體說來就兩件事情:拷貝APK 和 解析APK,解析APK主要是解析 AndroidManifest.xml,以便獲得它的安裝資訊。在安裝的過程中還會這個應用配置設定 Linux使用者ID 和 Linux使用者組ID(以便它可以在系統中擷取合适的運作權限)。

涉及的三個程序

  • PackageInstaller程序:PackageInstaller事實上是一個應用,它負責APK安裝以及解除安裝過程中與使用者的互動流程。
  • SystemServer程序:該程序主要運作的是系統服務,APK的安裝、解除安裝和查詢都由PackageManagerService負責,它也是Android核心系統服務的一種,在SystemServer裡初始化系統服務的時候被啟動。
  • DefaultContainerService程序:DefaultContainerService也是一個單獨的程序,它主要負責檢查和複制裝置上的檔案,APK的複制就是由DefaultContainerService來完成的。

apk 解析流程

  • Android不同類型

    /system/framwork:儲存的是資源型的應用程式,它們用來打包資源檔案。

    /system/app:儲存系統自帶的應用程式。

    /data/app:儲存使用者安裝的應用程式。

    /data/app-private:儲存受DRM保護的私有應用程式。

    /vendor/app:儲存裝置廠商提供的應用程式。

  • DEX的dexopt流程

    dexopt操作實際上對DEX檔案在執行前進行一些優化,但是不同的虛拟機操作有所不同。

    Davlik:将dex檔案優化生成odex檔案,這個odex檔案的字尾也是dex,儲存在/data/dalvik-cache目錄下。

    ART:将dex檔案翻譯生成oat檔案

如何修改 & 反編譯APK軟體包?

如果隻是修改程式包的一些圖檔/assets資源,直接在電腦上用解壓縮工具,解壓後就可以修改替換,但是重新打包後需要重新簽名,否則沒有簽名或者簽名校驗不正确的應用是無法安裝成功的。

而如果想要修改apk包中其他的已經編譯後的檔案,則需要反編譯。由于 Android 本質上就是一個 Java 虛拟機,而 classes.dex 檔案則是衆多 .class 檔案的打包集合,一般我們先要使用 dex2jar 将 classes.dex 解包為 Java jar 檔案,然後再通過 JD-GUI 将 jar 檔案的 .class 檔案反編譯為 .java 源碼。

整個反編譯dex的過程原理大緻簡單來說就是這樣,但是實際操作起來難度不小,因為很多程式都經過了混淆加密處理(比如QQ,微信等等大公司的軟體不可能讓人分分鐘反編譯破解,否則整個安卓APP世界還不亂套了...)

對于apk程式包其他的一些xml布局檔案,直接打開是亂碼怎麼辦?dex位元組碼都能反編譯成功,xml就更簡單一些了。網上有很多現成的工具,比如 AXMLPrinter2.jar ,可以直接解碼反編譯xml檔案,當然執行 .jar檔案需要在電腦上事先安裝好 JRE(Java運作環境)喲!

關于 Android 應用的反編譯這裡僅是簡單介紹一下原理和過程,明白了解一下就好。具體的方法百度一搜一大把。

虛拟機

安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機
安卓逆向_1 --- 逆向環境配置、APK 檔案結構、APK 打包流程打造年輕人的第一套安卓逆向環境!1. 逆向環境配置2. APK 檔案結構3. APK 打包流程4. APK 安裝流程虛拟機