綁定帳號登入

Android 台灣中文網

打印 上一主題 下一主題

[教程] APK Crack 反編譯、代碼分析、重新打包簽名教學

[複製連結] 查看: 12879|回覆: 2|好評: 0
跳轉到指定樓層
樓主
fam1001 | 收聽TA | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
發表於 2016-3-24 13:25

馬上加入Android 台灣中文網,立即免費下載應用遊戲。

您需要 登錄 才可以下載或查看,沒有帳號?註冊

x
基本準備

我們需要一些基本的工具進行一些主要的工作。如果你是一個會做Android APK漢化的朋友,那麼你應該對這些工具非常熟悉:

第一個工具是android-apktool,A tool for reengineering Android apk files 。這個工具是我們完成APK Crack的核心,利用它實現APK檔案的反編譯和重新打包。它是Google Code上一個非常著名的開源項目,大家可以在Google Code的網頁上獲取它和它的Wiki、源碼及其他相關訊息。網址是:http://code.google.com/p/android-apktool/

第二個工具是Auto-sign。這個工具實現的是APK打包後的簽名工作,屬於一個小工具。

除了這些基本工具外,為了更好的分析代碼,你可能還需要用到一些其他工具,例如:dex2jar和jd-gui等,這裡不做詳述。

反編譯

如果你是一個經常漢化APK程式的朋友,那麼反編譯這一步你肯定不會陌生。不過,既然這篇文章側重於基本流程講解,那麼這一步想來是不能省掉的。所以,覺得囉嗦的朋友,請跳過。首先我們需要有一個待反編譯的APK。這裡我自己寫了一個HelloWorld的APK,代碼如下:
  1. package com.zh_weir.helloworld;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. public class MainActivity extends Activity {
  5.      /** Called when the activity is first created. */
  6.      @Override
  7.      public void onCreate(Bundle savedInstanceState) {
  8.          super.onCreate(savedInstanceState);
  9.          setContentView(R.layout.main);
  10.      }
  11. }
複製代碼

我們通過android-apktool對這個APK進行反編譯。對於android-apktool的使用,我就不做太多翻譯的工作,直接給出說明文件吧。簡單一句話,就是命令行執行。
  1. Apktool v1.3.2 - a tool for reengineering Android apk files
  2. Copyright 2010 Ryszard Wi?niewski <[email protected]>
  3. Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
  4. Usage: apktool [-v|--verbose] COMMAND [...]
  5. COMMANDs are:
  6.     d[ecode] [OPTS] <file.apk> [<dir>]
  7.         Decode <file.apk> to <dir>.
  8.         OPTS:
  9.         -s, --no-src
  10.             Do not decode sources.
  11.         -r, --no-res
  12.             Do not decode resources.
  13.         -d, --debug
  14.             Decode in debug mode. Check project page for more info.
  15.         -f, --force
  16.             Force delete destination directory.
  17.         -t <tag>, --frame-tag <tag>
  18.             Try to use framework files tagged by <tag>.
  19.         --keep-broken-res
  20.             Use if there was an error and some resources were dropped, e.g.:
  21.             "Invalid config flags detected. Dropping resources", but you
  22.             want to decode them anyway, even with errors. You will have to
  23.             fix them manually before building.
  24.     b[uild] [OPTS] [<app_path>] [<out_file>]
  25.         Build an apk from already decoded application located in <app_path>.
  26.         It will automatically detect, whether files was changed and perform
  27.         needed steps only.
  28.         If you omit <app_path> then current directory will be used.
  29.         If you omit <out_file> then <app_path>/dist/<name_of_original.apk>
  30.         will be used.
  31.         OPTS:
  32.         -f, --force-all
  33.             Skip changes detection and build all files.
  34.         -d, --debug
  35.             Build in debug mode. Check project page for more info.
  36.     if|install-framework <framework.apk> [<tag>]
  37.         Install framework file to your system.
  38. For additional info, see: http://code.google.com/p/android-apktool/
複製代碼

通過apktool d HelloWorld.apk的命令,我們就完成了一個簡單的APK的反編譯工作。得到了一個叫做「HelloWorld」的資料夾。你可以看見資料夾下有Manifest檔案,有反編譯出的res資源檔案。這些東西都是平時漢化特別關心的,而不是我們要注意的重點。我們需要注意的是一個叫做「smali」的資料夾。

仔細觀察,你會發現這個資料夾下的檔案組織結構和我們的Android工程中java源碼的組織結構幾乎一致。只不過Java檔案被.smali的檔案取而代之了。我們用文本編輯器開啟這些.smali檔案,你會發現它們都是可識別的、並且非常「整齊」的文本檔案,大致如下:
  1. .class public Lcom/zh_weir/helloworld/MainActivity;
  2. .super Landroid/app/Activity;
  3. .source "MainActivity.java"
  4. # direct methods
  5. .method public constructor <init>()V
  6.     .locals 0
  7.     .prologue
  8.     .line 6
  9.     invoke-direct {p0}, Landroid/app/Activity;-><init>()V
  10.     return-void
  11. .end method
  12. # virtual methods
  13. .method public onCreate(Landroid/os/Bundle;)V
  14.     .locals 1
  15.     .parameter "savedInstanceState"
  16.     .prologue
  17.     .line 10
  18.     invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
  19.     .line 11
  20.     const/high16 v0, 0x7f03
  21.     invoke-virtual {p0, v0}, Lcom/zh_weir/helloworld/MainActivity;->setContentView(I)V
  22.     .line 12
  23.     return-void
  24. .end method
複製代碼

Smali檔案其實就是dalvik虛擬機執行的dex位元組碼檔案對應的彙編檔案了。如果你瞭解Java虛擬機的彙編語言Jasmin的話,你會發現兩者的語法非常相似。關於smali的語法等問題就不深入下去了,如果你想瞭解更多,可以存取Google Code上Smali項目主頁:http://code.google.com/p/smali/

代碼分析與修改

即使你不會Jasmin語法,你也能很容易看明白上面的彙編代碼。需要指出的是,apktool反編譯出來的彙編代碼同樣也是面向對象的,而不是面向過程的。這點和C++的反彙編可能有所不同。

根據上面的代碼,我們可以看出,這個MainActivity的類有兩個成員方法。一個是預設的構造函數;另一個就是我們重載的OnCreate方法了。

在java彙編中,每個成員方法需要首先申明自己所使用的局部變量的個數,以便實現分配存儲空間。例如OnCreate使用了一個局部變量,就聲明:.locals 1 。後面則使用v0表示。

在一個非靜態的成員方法中,p0代表的是這個類本身的引用,相當於this,p1開始才是函數的參數;而對於靜態方法,由於沒有this指針,所以p0就是函數的第一個參數。(其實本身this指針就是作為一個隱含的參數傳遞給非靜態成員函數的)。

通過分析上面Oncreate的彙編代碼,我們可以知道,它首先是調用super類的onCreate方法,然後再setContentView設定顯示。其中I、V等表示的是函數的參數和返回變量的類型,這是通用做法,這裡就不多做說明了。

分析到這一步,你是否發現一個問題?那就是如果我們按照同樣的語法修改或者增刪一個語句,是否就可以實現對程式的修改了呢?答案是肯定的。

例如,我們希望這個APK程式在執行時會彈出一個Toast,提示它被破解了。用Java的話,應該這樣表述:
  1. Toast.makeText(this, "I"m Cracked!", Toast.LENGTH_LONG).show();
複製代碼

而用Java彙編的話,則應該表述為這樣:
  1. const-string v0, "I"m Cracked!"
  2. const/4 v1, 0x1
  3. invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
  4. move-result-object v0
  5. invoke-virtual {v0}, Landroid/widget/Toast;->show()V
複製代碼

OK,只要我們將這段代碼插入到原來程式的OnCreate中,再重新打包程式,我們就能實現在這個程式執行時彈出Toast了。

改之後的代碼,大致如下:
  1. # virtual methods
  2. .method public onCreate(Landroid/os/Bundle;)V
  3.     .locals 2
  4.     .parameter "savedInstanceState"
  5.     .prologue
  6.     .line 11
  7.     invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
  8.     .line 12
  9.     const/high16 v0, 0x7f03
  10.     invoke-virtual {p0, v0}, Lcom/zh_weir/helloworld/MainActivity;->setContentView(I)V
  11.     .line 14
  12.     const-string v0, "I"m Cracked!"
  13.     const/4 v1, 0x1
  14.     invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
  15.     move-result-object v0
  16.     invoke-virtual {v0}, Landroid/widget/Toast;->show()V
  17.     .line 15
  18.     return-void
  19. .end method
複製代碼


重新編譯打包簽名

修改完成後,我們就可以對這個資料夾進行編譯打包了。同樣,我們使用的工具是apktool。通過命令apktool b HelloWorld,就可以實現程式編譯打包了。這時會在這個資料夾下生成兩個資料夾:存放中間檔案的資料夾build和存放最後的apk檔案的資料夾dist。

如果一切順利的話,你就可以在dist資料夾中看到我們修改後的HelloWorld.apk了。不過需要注意的是,這個APK檔案是還沒有簽名的,所以無法安裝執行。我們還需要進行最後一步,那就是對這個APK進行簽名。

簽名我們需要用到的工具是Auto-sign。它主要是利用批處理命令,使用signapk.jar對APK檔案進行簽名的。你可以用記事本開啟Sign.bat,看看它的具體調用關係。關鍵如下:
  1. java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk
複製代碼

OK!到此,我們對這個APK的Crack就結束了。現在在模擬器或者Android機器上安裝上簽好名的APK程式,執行試試。一切與我們的預期相同~
「用Android 就來APK.TW」,快來加入粉絲吧!
Android 台灣中文網(APK.TW)

評分

參與人數 14碎鑽 +10 幫助 +14 收起 理由
zechacker + 1 鼓勵一下!
gu3067 + 1 + 1 非常讃
z0789184 + 1 + 1 非常讃
kokoro9913 + 1 + 1 很給力!(雖然我看不懂
et416000 + 1 + 1 非常讃
李嘎嘎 + 1 + 1 非常讃
kaiouki + 1 + 1 非常讃
馬克杯~杯 + 1 姐很想給你一個吻,但不現實,還是給分吧.
0506abon + 1 偶像,看完你的內容,讓我找到了活著的意義.
ae0956813083 + 1 很給力!

查看全部評分

收藏收藏22 分享分享2 分享專題
用Android 就來Android 台灣中文網(https://apk.tw)
回覆

使用道具 舉報

沙發
ae0956813083 | 收聽TA | 只看該作者
發表於 2016-11-7 04:13
ありがとう~~~~~~~~~~~~~~~~~~~~
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則