Android apk 逆向工程研究﹣破解 MyTV HD 機種限制手記

日前網上有 MyTV X HTC One HD 版 Android app 流出,但由於程式限制了只有 HTC One 手機纔可以使用,大部份用家得物無所用。當然,道高一尺,魔高一丈,很快的就有人放出破解版,解除了這個限制,Android 全機種都可以用了。

他是如何做到破解的呢?這篇文章會拆解一下這個流出來的 apk 檔,並提供一些工具給大家分析代碼,西傑相信這個過程並不困難,大部份 programmer 學一會兒就應該看得懂!(當然並不是所有 apk 檔都可以用同一方法來破解,加了殼的 apk 就比較困難了)

利申:本文章僅供教學用,請勿嘗試公開發佈破解檔案

工欲善其事,必先利其器,這次我們會用到 dex2jar 這個工具,它的用途是幫我們把 apk 爆開成多個 bytecode 檔,我們就是透過修改這些 bytecode 檔來破解 Android app 的了。值得一提的是,dex2jar 的 wiki 已經清楚說明如何把 apk 檔反譯成 bytecode 檔和如何重新打包,讀完以下教學仍不清楚的話可以參考一下。

下載了 dex2jar 之後,我們就可以開始反譯 apk 檔了,dex2jar 提供的例子是這樣:

# convert classes.dex in test_apk-debug.apk to test_apk-debug_dex2jar.jar
d2j-dex2jar.sh -f -o test_apk-debug_dex2jar.jar test_apk-debug.apk
# verify jar
d2j-asm-verify.sh test_apk-debug_dex2jar.jar
# convert to jasmin format
d2j-jar2jasmin.sh -f -o test_apk_jasmin test_apk-debug_dex2jar.jar

三個步驟,第一步將 apk 檔內的 classes.dex 抽出來並反譯成 jar,classes.dex 就是主程式所在的地方。第二步是驗証 jar 檔(但我不清楚有什麼用,估計是驗証它是不是完整可執行的檔案吧)。第三步是把 jar 檔轉為 jasmin 格式(大概是 Java bytecode 的意思)。

應用在 mytv 上,上列三個 command 應為:

./d2j-dex2jar.sh -f -o ../apk/mytvhd_prod.jar ../apk/mytvhd_prod.apk

./d2j-asm-verify.sh ../apk/mytvhd_prod.jar

./d2j-jar2jasmin.sh -f -o ../apk/mytvhd_prod ../apk/mytvhd_prod.jar

這個時候就應該會有一個裝滿 .j 檔的資料夾,這些 .j 檔就是我們要研究的 bytecode 檔了。由於  MyTV 程式啟動時就已經會欄截非 HTC One 用家,因此我們當然要看看 MyTV 最開始時的那個 Activity 發生了什麼,到哪裏找呢?manifest 吧,不過說實話,有開發 Android 經驗的 programmer 應該大約估計到那個 Activity 放在何處的吧!就是 com.tvb.mytvhd.activity.StartUpActivity 了!開啟 StartUpActivity.j 後,你會看到一大堆陌生的代碼(估計你不會常常看 bytecode 吧...)

不要緊,你要仔細研究的話可以到維基看看 Java bytecode 有什麼指令可以用,但這裏就只是快速找尋所需代碼做示範!有開發 Android app 的 programmer,Activity 啟動時執行的是哪個 method(不計 constructor)?是 onCreate!在代碼中搜尋一下吧。

看到了嗎?很短的一個 method,有注意到 229 行的這句嘛?

invokespecial com/tvb/mytvhd/activity/StartUpActivity/error_nonHTC()V

又什麼什麼 invoke,又什麼什麼 error_nonHTC ,還不是我們要找的東西!?仔細研究一下上文下理。

執行 isHTCOne(),ifeq 就是如果結果等如 0 (false) 的話就跳到 L0,而 L0 就是執行 error_nonHTC(),很明顯就是要用來告訴用家它不是 HTC 機然後退出程式,那要如何改呢?方法有二:一,ifeq 轉為 ifne,那麼不是 HTC One 就可以看到,反而 HTC One 看不到;二,把整段檢查代碼刪掉,速度還可以快一點不用檢查!來試試方法二吧。

只要把相關的 ifeq 和 isHTCOne() 以及 L0: 下的檢查代碼刪掉即可!

重新打包 apk 檔,可用以下 command!

# build jar
d2j-jasmin2jar.sh -f  -o test_apk_jasmin.jar  test_apk_jasmin/
# verify jar
d2j-asm-verify.sh test_apk_jasmin.jar
# convert to dex
d2j-jar2dex.sh  -f -o classes.dex test_apk_jasmin.jar
# make a copy
cp test_apk-debug.apk test_apk-debug-toast.apk
# replace classes.dex in test_apk-debug-toast.apk
zip -r test_apk-debug-toast.apk classes.dex
# sign the apk
d2j-apk-sign.sh -f -o test_apk-debug-toast-signed.apk test_apk-debug-toast.apk


把例子中的檔案名換成相對應的 mytvhd 就可以了!


#把 jasmin 代碼重新打包成 jar 檔
./d2j-jasmin2jar.sh -f -o ../apk/mytvhd_prod_new.jar ../apk/mytvhd_prod

#驗証一下
./d2j-asm-verify.sh ../apk/mytvhd_prod_new.jar 

#把 jar 檔變成 Dalvik VM 的 dex 檔
./d2j-jar2dex.sh -f -o ../apk/classes.dex ../apk/mytvhd_prod_new.jar

#複製一份新的 apk 以免改動原有 apk
cp ../apk/mytvhd_prod.apk ../apk/mytvhd_prod_new.apk

#把新的 dex 檔放到 apk 中,取代原有的 classes.dex
zip -r ../apk/mytvhd_prod_new.apk ../apk/classes.dex 

#sign apk
./d2j-apk-sign.sh -f -o ../apk/mytvhd_prod_new_signed.apk ../apk/mytvhd_prod_new.apk


失敗了,為什麼!?呵呵,西傑第一次嘗試就為這個蠢問題花了不少時間,原因其實很簡單,把新的 apk 解壓縮一下就可以看到問題。

看到嗎?有兩個 classes.dex,是 zip command 用錯了,classes.dex 應該要放在根目錄纔可以,那解決方法呢?很簡單,把 apk/classes.dex 拉出來放在根目錄然後再 zip 一次和 sign 一次就好了。

成功了!其實破解軟件沒有大家想像的那麼難,現成工具已經做得很好,只要花少許時間分析一下人家的代碼就可以了。當然,我還是那句,本篇文章只是為了教學,研究一下 apk,看看如何做逆向工程,並不是要你們把天下間的軟件都破下來,請尊重別人!

參考:

https://code.google.com/p/dex2jar/wiki/ModifyApkWithDexTool

http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings


http://dukeland.hk/2013/05/13/android-apk-reverse-engineering-cracking-the-mytv-hd-restriction/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章