2012年10月14日 星期日

把玩"魔術師" -- 認識、把玩 APK 檔


把玩"魔術師" -- 認識、把玩 APK 檔

This document is provided as is. You are welcomed to use it for non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu

請勿轉貼
看其他教材

在製作自己的 ROM 之前,我們假設你已經可以取得必要的 image 檔或者 由網友已經製作好的 ROM;如果是 image 檔,你需要至少 boot.img 以及 system.img;如果是網友已經製作好的 ROM,大都以 zip 檔的型態出現。 如果你使用 Kitchen 的話,不論是 image 檔或者 zip 檔,它都可以完整的 把整個 ROM 解開來。解開 ROM 之後,一般我們會看到 boot.img (用來開機的 映像檔),META-INF 裡面包含一些簽章以及刷 ROM 過程的程式,以及 system 目錄。由於製作 ROM 只是修改 ROM 的部分內容 -- 嚴格的說,一些 文件檔、apk 檔等,我們並不會真正的修改程式碼,因此認識 apk 檔就成為 非常重要的概念。這個階段結束了之後,或許我會投入 Android 的程式, 也就是 apk 的開發。


為了說明方便,我們使用的範例是 2010 年 9 月初由加拿大電信商 Rogers 釋出的 HTC Magic 2.1 官方 ROM,加上 xda 網友 campychimp 套上的 root;該 ROM 的討論串 分別在 (rom) Rogers stock rom with root, Without rogers apps, by capychimp [12 sep 2010] 以及 capychimp 製作的 RCMagic,ROM 的下載點在 Rogers_21_capychimp.zip。請利用你常用的解壓縮軟體對 Rogers_21_capychimp.zip 進行 解壓縮,如上一段的說明,你會看到 META-INF、system、boot.img、以及 installbusybox;另外,所有的 apk 檔都在 system/app 以及 system/framework 內。
請仔細看一下 system/app 的內容,你會發現這個目錄內有兩種檔案, 一種的副檔名是 apk,另一種的副檔名是 odex。簡單的說,apk 是 Android 平台的 應用程式包裹(Android application package);它包含了一個應用程式執行時 所需要的程式碼(副檔名為 .dex)、程式所需的資源(例如定義檔、圖片等)。 .dex 檔是 Android 的執行檔,是經由編譯 Java 原始碼後所產生的,名稱為 dex 的主因是因為 Android 的 JVM 叫作 Dalvik,而可以在 Dalvik 中 Executable(執行的)就叫 dex,也就是類似在一般電腦平台編譯 Java 原始碼 之後的 .class 檔。那麼什麼是 odex 檔呢?我們可以把它想成 "optimized" dex 檔(最佳化後的 dex 檔),這個檔案的目的就是希望能讓 Java 程式能夠 順暢的在手機上執行(知不知道最快速手機跟最快速的個人電腦比較起來 差多少?)而來的;雖然說是這樣說,但是執行 odex 以及沒有 odex 的情形來 比較,在執行上我個人感覺不出差異,但是在開機的過程確實 odex 遠遠優於 沒有 odex 的情形。最後要提醒大家的是,我忘了我在什麼地方看到,如果在一個 目錄下看到同時有 apk 和 odex 的同樣名稱的檔案,那麼這個 apk 無法單獨 修改,你必須將他們兩個檔案 deodex 之後變成一個單獨的 apk 檔之後,才能 修改 apk 檔。
有了基礎的認識之後,我們需要準備能夠處理 apk 檔的工具,以及一個範例 apk 檔, 準備的步驟如下:
  1. 能夠處理 apk 的工具名稱為 apktool,它的網頁在 android-apktool: Tool for reengineering Android apk files。請到其下載頁下載工具,由於我們使用 Windows 的環境, 所以我們需要下載 apktool1.3.2.tar.bz2 以及 apktool-install-windows-2.2_r01-3.tar.bz2。
  2. 請新增 f:\apktool 並將下載的 bz2 解壓縮到該目錄內;完成後, 在 f:\apktool 將有 aapt.exe、apktool.bat、以及 apktool.jar 三個檔案。
  3. 為了方便說明,我們從 Rogers_21_capychimp.zip 的 system/app 中找到一個 獨立的 apk 檔,該檔案名稱為 YouTube.apk;請將該檔案放置於 f:\apktool。 如果你找不到一個獨立的 apk 檔,我們建議你使用 dsixda 的 Kitchen 將成雙成對 的 apk 和 odex 進行 deodex 的工作,我們假設你會使用 kitchen 或者已經看過 我之前寫的 安裝 Kitchen。 以 Rogers_21_capychimp.zip 為例,請啟動 kitchen;然後輸入 "1" 來開始烹調 Rogers_21_capychimp.zip,輸入 "1" 之後的畫面如下:
    請選擇適當的 ROM,在本範例中也就是 Rogers_21_capychimp.zip;如果我們 擁有 boot.img 和 system.img 檔,我們也可以將該檔案放置於 f:\cygwin\home\JLU\kitchen\original_update 的目錄內。 輸入 "1" 之後的畫面如下:

    該畫面顯示 kitchen 已經將 ROM 適當的解壓縮,並將內容放置於工作目錄中, 在本例中,其目錄名稱為 WORKING_101510_121057,而該目錄為 kitchen 的子目錄。請 "Enter" 兩次,之後會顯示如下的畫面:

    該畫面顯示 ROM 的資訊,從以上資訊我們可以知道,Rogers_21_capychimp.zip 是 一個 Android 2.1-update1 的 ROM,而且已經被 rooted 過,且包含有 BusyBox。 看完以上資訊,可以再按一次 "Enter" 就可以回到 kitchen 的主畫面。
  4. 假設我們希望能夠解讀 Browser.apk 的內容,由於該 apk 檔也有一個相對應的 odex 檔,所以我們必須對它加以 deodex,而 deodex 的過程如下。首先,請在主選單 選擇 "0"(ADVANCED OPTIONS;進階選項),輸入之後的畫面如下:
    然後,我們選擇 "11"(Deodex files in your ROM;將 ROM 中的檔案進行 deodex), 輸入之後的畫面如下:

    由於我們只想 deodex Browser.apk 的內容,所以我們選擇 "s"(Deodex a single file; Deodex 一個檔案),輸入之後的畫面如下:

    請注意畫面中,紅色框框的部分,Browser.odex 的檔案編號是 5;然後,請繼續按 空格鍵直到以下畫面出現:

    由於我們希望 deodex Browser.odex,所以我們輸入 5,然後再按一次 Enter;Deodex 完成後,畫面如下:

    到這裡,我們已經將 Browser.odex deodex 完畢。我們可以選擇輸入 "x"(Exit;結束)回到進階選項的選單。我們所要的 Browser.apk 就在 WORKING_101510_121057/system/app 內,請將其複製到 f:\apktool
















完成了以上的準備工作,我們就可以開始處理 apk 檔了。首先,我們先將 YouTube.apk 進行解壓縮,其過程如下所述:
  1. 請開啟一個命令提示字元視窗,並進入 f:\apktool 目錄。
  2. 請執行 apktool d YouTube.apk,執行後的畫面如下:
  3. 解壓縮 YouTube.apk 之後,apktool 會在 f:\apktool 產生一個 YouTube 的 子目錄,而該子目錄包含 YouTube.apk 的內容,其畫面如下:
    畫面中,smali 包含 YouTube.apk 中的類別檔,而 res 包含執行該類別檔所需要 的資源檔(resource;簡稱 res)。類別檔所需要的資源檔包含圖示、以及設定 資料,所以 res 目錄中的內容,如以下畫面所示:

    res 目錄中的詳細內容以後在說明 Android 程式開發的時候再詳述,在此我們 先說明跟中文化(或者所謂的多國語言化)有關的檔案,也就是 values 目錄。 所有的 res 目錄中幾乎都包含 values 目錄,該目錄中包含原始語系(大多為 英文)中所出現的訊息資料。
  4. 從以下畫面,我們可以看出 values 目錄中 strings.xml 的內容,其中請特別注意 紅色框框的部分,一個是 Most viewed,其名稱為 most_viewed_videos;另一個是 Most discussed,其名稱為 most_discussed_videos。
  5. 如果要將其中文化的話,我們需要一個名為 values-zh-rTW 的目錄(如果是 簡體中文的話,那麼我們就需要一個名為 values-zh-eCN 的目錄)。在 values-zh-rTW 的目錄中,我們也可以發現一個 strings.xml,將其打開後,我們發現其內容如下列 左圖:
    請仔細比較左圖中紅色框框以及之前英文版畫面的紅色框框部分,你應該可以輕易的看出 在名稱為 most_viewed_videos 的標籤內容為 Most viewed;而在中文版中 名稱為 most_viewed_videos 的標籤內容為"觀看次數最多的影片"。相同的, 在名稱為 most_discussed_videos 的標籤內容為 Most discussed,其中文版為 "最多評論的影片"。另外,在英文版中,紅色框框的下方分別定義了名稱為 most_viewed_videos_lower_case 以及 most_discussed_videos_lower_case 的 設定,由於中文並沒有大、小寫的區分,因此中文版中並不需要定義該兩項設定。
    在右圖中的紅色框框,我們分別勾勒出定義後的效果。這樣看起來,中文化設定 還蠻簡單的,只是設定起來也是很煩的,想想看,我們總共有多少個 apk 檔,我們 必須一個、一個的去做修正。(說到這裡,不得不對 HTC 再次 抱怨一下,這裡的內容說明了 2.1 版的內容其實都已經中文化完畢了,但是 HTC 為了 營運策略的關係,把這個 ROM 稍微閹割了一下,讓中文無法顯示,唉)
  6. 為了實驗一下剛剛的說法,假設我們想把"觀看次數最多的影片"修改為 "最熱門的影片",請將該 strings.xml 的內容進行修改;修改後,我們需要把 這些檔案重新打包成 YouTube.apk,打包的指令為 apktool b YouTube YouTube.apk,執行的畫面如下:
    完成後,請將新產生的 YouTube.apk 複製到 WORKING_101510_121057/system/app 中。
  7. 雖然我們已經重新產生了 YouTube.apk,但是我們還不能立刻產生新的 ROM, 這是由於 ROM 的安全機制,所有的 apk 檔在安裝前都必須先進行簽名,但是為了 使用方便,也同時能確保所有的 apk 都簽過名(我們有可能修改了多個 apk 檔), 因此我們使用 kitchen 來簽章,簽章的方式必須從進階選項的畫面開始(我們 假設你之前的 kitchen 視窗還在);請在進階選項的畫面中輸入 21(Sign APK file(s); 對 APK 檔進行簽章),你會看到如下的畫面:
    為了避免少簽了章,我們選擇 "a"(Sign all *.apk in working folder;將工作 目錄內的所有 apk 檔進行簽章),完成後的畫面如下:

    簽章完成後,我們就可以利用 "x"(Exit;結束)、"0"(BACK TO MAIN MENU; 回到主選單);然後在主選單輸入 "99"(Build ROM from working folder; 從工作目錄建立新的 ROM);新的 ROM 會被放置於 OUTPUT_ZIP,如以下畫面 所示(本例的 ROM 名稱為 signed_102510_145942.zip):

    完成的 ROM 可以將它放到手機的 Sdcard 中,然後經由 recovery 將它刷到手機中, 再次強調,刷機是有風險的,只有"你"自己要負起所有的後果,跟別人無關。



















參考資料:

  1. Dalvik Optimization and Verification With dexopt
  2. Glossary of Android Dev Guide
  3. Optimized DEX files


Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu






沒有留言:

張貼留言