2012年7月13日 星期五

Android Decompile 實例 via smali

※此篇文章僅供學術交流,嚴禁轉載及引用或做其他用途※
※此處不提供任何付費軟體,如有興趣請支持正版※
※請遵循所有 Goolge 的規範以及協議※

這邊要介紹利用之前提到的 decompile 工具來實際
反編譯一個程式,並達到我們需要的目的。

要先準備的工具有:
1. Smali (也要有 baksmali)
2. Dex2Jar
3. JD-GUI
4. AndroidResEditor

前三個可以在之前的文章找到,第四個 Google 一下應該會有
或者到 Gphonefans 下載 (PS: 中級會員以上限定)
這個主要是做 signature 用的,所以也可以用 Android SDK
提供的工具來做簽章


當然不要忘記一定要有 Java 執行環境 (JRE or JDK)

另外,也有工具提供直接處理整個 apk 的: apktools , apktool 裡面包含有
smali  和 baksmali ,其實算是很齊全的工具,如果有要順便改 xml 的人可以
改用這個。 不過 apktool 沒有簽章的動作,所以包裝好的 apk 記得要做簽章 。




這次實例的苦主是 Note Everything 這個記事軟體,先幫忙打一下廣告,
這個軟體真的算是一個不錯的記事軟體,文字、條碼、手寫、圖片記事,
完整版還有 錄影記事、代辦事項... 等,還可以定選到通知列、設定鬧鈴。
是一個功能很齊全的記事軟體。


首先到 Play 下載安裝這個免費的軟體,並且利用任何的輩份程式把 APK
檔備份出來,我個人是採用 系統資訊Pro


將匯出的 apk 檔找個地方放好,並用 7-zip  或者 WinRAR 軟體打開,可以
看到裡面會有一個 classes.dex,解壓縮出來備用。


將下載完的這些檔案都放好,接下來會先用到 dex2jar 和 JD-GUI,都先解
壓縮出來備用。

【將 dex 轉為看得懂的 java code】
首先到 dex2jar 裡面,可以看到有很多的檔案,都有各自的功能,
這邊先開啟命令提示字元,執行 :dex2jar.bat classes.dex
完成後可以看到多出了一個 classes_dex2jar.jar 的檔案


 接著使用 JD-GUI 打開這個 jar 檔案,就可以看到裡面原始碼。



這邊只是利用這個工具來找出我們需要修改的程式碼在哪邊而已。


PS:decompile 成我們看得懂的 java code 不會是完美的,有可能會出現一些
奇怪的語法 或者根本是錯誤敘述,這些都是正常現象,反正我們只要看一下大
內容,這部分就還好了



【找到 Pro Version 是如何檢查的】

 既然我們的目的是 crack , 那麼一定就先要檢查看看到底這個程式
是如何驗證Pro Version,首先要找到這隻程式的 main activity 是哪個。
方法有很多,主要是把  apk 檔案裡面的 AndroidManifest.xml 給解析出
,這邊我們可以直接利用 AndroidResEditor 開啟這個 xml,只要看一
下關鍵字:
有寫過 android 程式的人應該對這些東西不陌生,可以看到主要的 activity 是
de.softxperience.android.noteeverything 底下的 NoteEverything 這個 class。


JD-GUI 開啟這個 class , 一樣先找 onCreate ,因為每個 android 程式都是從
onCreate 開始的。
居然很幸運的看到了一個關鍵字,就是 PackageChecker.isProVersion(this);
可以合理推測,他就是掌控生殺大權的 method 了。
 
移到  PackageChecker 底下找到 isProVersion():
public static boolean isProVersion(Context paramContext)
  {
    if (mIsProVersion == null)
      mIsProVersion = Boolean.valueOf(checkPackageExists(paramContext,"de.softxperience.android.noteeverythingpro"));
    return mIsProVersion.booleanValue();
  }

也就是會先檢查 mIsProVersion 這個物件是否為 null ,如果是就要做驗證,看有
沒有安裝  pro key addon,接著傳回 mIsProVersion。

那麼我們的目的就很明顯了,只要讓這個 method 傳回 true 就可以讓程式認為
是 pro version 的版本(有安裝 pro addon)。
往下看,這個 PackageChecker 底下有一個 onRecive() 有可能
會讓 mIsProVersion 變回 null,所以我們採用的方式為:
 將  isProVersion() 改為:
public static boolean isProVersion(Context paramContext)
  {
    if (mIsProVersion == null)
      mIsProVersion = Boolean.valueOf(true);
    return true;
  }

這樣應該就萬無一失了。

立定目標後,接著就是著手進行修改了。


【修改 bytecode】
將 classes.dex 放到 smali 的目錄中,我們先把 dex 轉換成
Dalvik bytecode 的 smali 檔案,執行命令:
java -jar baksmali.jar classes.dex
如果成功了會出現一個 out 的資料夾

到這個資料夾裡面找到我們要的那支 PackageChecker:
de\softxperience\android\noteeverything\PackageChecker.smali

用 Notepad++ 或者任何你喜歡的文字編輯軟體打開,我們要找的是 isProVersion()
所以直接搜尋 isProVersion,找到 method 的地方,長得像這樣:
.method public static isProVersion(Landroid/content/Context;)Z
//(中間略)
.end method

基本上裡面有甚麼資料不重要,因為基本上要完全改寫,底下直接提供
改寫好的 code,有興趣的話可以研究一下 Dalvik bytecode 算是蠻容易
懂得。
.method public static isProVersion(Landroid/content/Context;)Z
    .registers 3
 .parameter "ctx"
    const/4 v1, 0x1
    sget-object v0, Lde/softxperience/android/noteeverything/PackageChecker;->mIsProVersion:Ljava/lang/Boolean;
    if-nez v0, :cond_b
    invoke-static {v1}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
    move-result-object v0
    sput-object v0, Lde/softxperience/android/noteeverything/PackageChecker;->mIsProVersion:Ljava/lang/Boolean;
    :cond_b
    return v1
.end method

這樣就算大功告成了,接著編譯回去,執行命令:
 java -jar smali.jar -o hacked.dex out
如果成功就會出現一個 hacked.dex 檔案,這就是完成的檔案:

接著把這個 hacked.dex 更名為 classes.dex 放回原本的 apk 裡面取代
掉原本的檔案就完成 99% 了。

最後,這個修改過的 apk 需要做重新簽章,否則無法順利安裝,直接開啟
AndroidResEditor 選擇「簽名」 =>「簽名 apk 檔案」
選取檔案後按下「立刻簽名」,在選擇輸出檔名就完成了。

接著把 apk 丟回去安裝就可以使用 pro 的功能了。
要注意的是,不同簽章的 apk 不能同時安裝,也就是要先移除原本 Market
抓的版本再安裝這個版本。

另外,說不定 pro addon 本身有其他功能的資料在裡面,這種 tricky 的方法
有可能會讓某些功能失效,例如:
這種方式用出來的 pro 版本「定時提示」 會無法運作(不會跳出提示)
這部分請自行斟酌了。

最後※本文章僅供學術交流使用,請勿利用所學進行非法或者商業行為※

3 則留言:

  1. 您好,想請問一下,解開的classes.dex,要如何加新的class進去呢??

    回覆刪除
    回覆
    1. 要加入新的 class 比較麻煩,屬於進階的部分。
      可以先開一個 Eclipse 專案 , 寫好後 decompile
      再加入目的資料夾中
      有興趣的話可以研究看看 Dalvik bytecode

      刪除