User Tools

Site Tools


study:apk-decompiler:250729-001:index

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

study:apk-decompiler:250729-001:index [2025/07/29 15:15] (current)
jethro created
Line 1: Line 1:
 +~~NOTOC~~
 +====== 人人都會的 Android Apk 反編譯 #5 (2025-07-29) ======
 +  * Source: [[https://​github.com/​aszx87410/​blog/​issues/​5]]
 +  * {{:​study:​apk-decompiler:​250729-001:​pasted:​20250729-150752.png?​300}}
 +===== Local Backup =====
 +  * 對於 Android 工程師來說,了解如何反編譯可以增進自己對 Android 底層的理解,也可以思考如何保護自己的 apk 不被反編譯。
 +  * 對於一般人來說,許多現成的工具可以幫助我們非常輕鬆的、只要打打幾個指令就可以反編譯 apk,看到 java source code,滿足自己的好奇心。
 +  * 本篇文章只介紹一些工具的使用,適合初學者觀看。若是想了解更底層的知識,可以參考文末附上的延伸閱讀。
 +===== 事前準備 =====
 +  * 首先,我們需要一個用來被破解的 apk,簡單用任何你平常熟悉的工具自己 build 一個就好了。基本架構很簡單,只要一個 MainActivity 跟兩個TextView就好:
 +  * <sxh java>​public class MainActivity extends Activity {
  
 +    @Override
 +    protected void onCreate(Bundle savedInstanceState) {
 +        super.onCreate(savedInstanceState);​
 +        setContentView(R.layout.activity_main);​
 +        TextView text = (TextView)findViewById(R.id.text);​
 +        text.setText("​Taiwan No1");
 +    }
 +}
 +<​LinearLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
 +    android:​layout_width="​match_parent"​
 +    android:​orientation="​vertical"​
 +    android:​layout_height="​match_parent">​
 +
 +    <​TextView
 +        android:​text="​@string/​hello_world"​
 +        android:​layout_width="​wrap_content"​
 +        android:​layout_height="​wrap_content"​ />
 +
 +    <​TextView
 +        android:​id="​@+id/​text"​
 +        android:​layout_width="​wrap_content"​
 +        android:​layout_height="​wrap_content"​ />
 +
 +</​LinearLayout></​sxh>​
 +  * 安裝到手機上之後,會看到這樣的畫面:\\ {{:​study:​apk-decompiler:​250729-001:​pasted:​20250729-150846.png?​300}}
 +===== 實際動手 =====
 +  * 好,這個就是我們要拿來測試的 apk 了!
 +  * 接著你需要一些非常好用的工具:
 +    * 1. [[http://​ibotpeaches.github.io/​Apktool/​|apktool]]
 +    * 2. [[http://​jd.benow.ca/​|jd-gui]]
 +    * 3. [[https://​sourceforge.net/​projects/​dex2jar/​|dex2jar]]
 +  * 如何安裝就不再贅述了,讀者們可以參考看看文件或是上網搜尋一下就會有一堆解答~
 +    * apktool是拿來把 apk 拆開用的,可以反編譯 apk 之後,看到 smali 檔案跟 resource
 +    * dex2jar可以把 apk 轉成 jar,再用jd-gui檢視 java code
 +  * 接著我們開啟 terminal,到剛剛那個示範 apk 的目錄底下,執行apktool d APKNAME.apk
 +    * {{:​study:​apk-decompiler:​250729-001:​pasted:​20250729-151004.png?​500}}
 +  * 執行以後,會自動生成一個APKNAME的資料夾,裡面就是反編譯出來的東西了。
 +    * <​sxh>​.
 +├── AndroidManifest.xml
 +├── apktool.yml
 +├── original
 +├── res
 +└── smali</​sxh>​
 +  * 其中比較值得講的是smali這個資料夾,其實這裡面就是你的 source code,只是格式不太一樣。
 +  * 你可以在smali這資料夾裡面找到你的MainActivity.java,內容如下:
 +  * (覺得長得很奇怪是很正常的事,但是認真多看幾眼,你會發現其實沒那麼難懂)
 +  * <sxh java>​.class public Lapktest/​huli/​com/​apkdecompile/​MainActivity;​
 +.super Landroid/​app/​Activity;​
 +.source "​MainActivity.java"​
 +
 +# direct methods
 +.method public constructor <​init>​()V
 +    .locals 0
 +
 +    .prologue
 +    .line 8
 +    invoke-direct {p0}, Landroid/​app/​Activity;​-><​init>​()V
 +
 +    return-void
 +.end method
 +
 +# virtual methods
 +.method protected onCreate(Landroid/​os/​Bundle;​)V
 +    .locals 2
 +    .param p1, "​savedInstanceState" ​   # Landroid/​os/​Bundle;​
 +
 +    .prologue
 +    .line 12
 +    invoke-super {p0, p1}, Landroid/​app/​Activity;​->​onCreate(Landroid/​os/​Bundle;​)V
 +
 +    .line 13
 +    const v1, 0x7f040019
 +
 +    invoke-virtual {p0, v1}, Lapktest/​huli/​com/​apkdecompile/​MainActivity;​->​setContentView(I)V
 +
 +    .line 14
 +    const v1, 0x7f0c0050
 +
 +    invoke-virtual {p0, v1}, Lapktest/​huli/​com/​apkdecompile/​MainActivity;​->​findViewById(I)Landroid/​view/​View;​
 +
 +    move-result-object v0
 +
 +    check-cast v0, Landroid/​widget/​TextView;​
 +
 +    .line 15
 +    .local v0, "​text":​Landroid/​widget/​TextView;​
 +    const-string v1, "​Taiwan No1"
 +
 +    invoke-virtual {v0, v1}, Landroid/​widget/​TextView;​->​setText(Ljava/​lang/​CharSequence;​)V
 +
 +    .line 16
 +    return-void
 +.end method</​sxh>​
 +  * 你可以仔細對照一下剛剛自己寫的 java code,會發現只是換了種格式而已:
 +  * <​sxh>​setContentView(R.layout.activity_main);</​sxh>​
 +  * 其實就等於
 +  * <​sxh>​.line 13
 +const v1, 0x7f040019
 +invoke-virtual {p0, v1}, Lapktest/​huli/​com/​apkdecompile/​MainActivity;​->​setContentView(I)V</​sxh>​
 +  * 你可能會好奇,這個0x7f040019是哪來的?
 +  * 事實上,你可以在res/​values/​public.xml這個檔案裡面找到答案:
 +  * <sxh xml><​public type="​layout"​ name="​activity_main"​ id="​0x7f040019"​ /></​sxh>​
 +  * 到這裡,應該就可以大概猜出 Android 在編譯時候的流程:
 +    * 1. 把所有資源檔壓縮、處理並且包在一起,產生id與記憶體位置對照表
 +    * 2. 把程式碼裡面所有的R.xx.xxx透過剛剛產生的表,換成實際的記憶體位置
 +    * 3. 把 java code 變成 smali code(有點像把 C 變成組合語言的程式碼那樣)
 +===== 修改 =====
 +  * 在剛剛的smali裡面,有這麼一段:
 +  * <​sxh>​.line 15
 +.local v0, "​text":​Landroid/​widget/​TextView;​
 +const-string v1, "​Taiwan No1"
 +
 +invoke-virtual {v0, v1}, Landroid/​widget/​TextView;​->​setText(Ljava/​lang/​CharSequence;​)V</​sxh>​
 +  * 讓我們把Taiwan No1換成T@iw@n n0!。
 +  * 還記得另一個TextView有用到R.string.hello_world嗎?
 +  * 在res/​values/​strings.xml裡面,可以找到這一串的定義:
 +  * <​sxh><​string name="​hello_world">​Hello world!</​string></​sxh>​
 +  * 改成:
 +  * <​sxh><​string name="​hello_world">​HELLO WORLD</​string></​sxh>​
 +  * 確定都有改完以後,就可以把這些程式碼再度「組裝」回去。
 +  * 還記得剛剛反編譯的指令嗎?apktool d APK_NAME.apk
 +  * 這邊的d就是decompile的意思,所以如果要逆向組裝回去,就是b,build。
 +  * <​sxh>​apktool b APK_NAME</​sxh>​
 +  * 執行完之後可以在APK_NAME/​dist下面找到一個 apk。
 +  * 但要注意的是這個 apk 還沒有被 sign 過,因此無法安裝。
 +  * 可以隨便生成一個 keystore 或是找現成的來簽署。
 +  * <​sxh>​jarsigner -verbose -digestalg SHA1 -keystore ~/​KEY.keystore APK_NAME.apk KEY_ALIAS</​sxh>​
 +  * 安裝完以後就會看到這樣的畫面:
 +  * {{:​study:​apk-decompiler:​250729-001:​pasted:​20250729-151311.png?​300}}
 +  * 沒錯!就是這麼簡單,一個 apk 就這樣被修改了!
 +  * 可是smali的程式碼不好懂,能不能直接看到 java code呢?
 +  * 這時候剛剛推薦的工具dex2jar與jd-gui就派上用場了
 +  * 前者可以把 apk 變成 jar,後者可以開啟一個 jar 並且顯示 java code
 +  * 兩個組合在一起,就可以直接看到原本的程式碼了
 +  * dex2jar下載下來之後會有一堆的 shell script,dex2jar就是我們想要的那個
 +  * <​sxh>​./​d2j-dex2jar.sh app.apk</​sxh>​
 +  * 執行完之後會有一個 jar,用 jd-gui 打開,會看到你的程式碼一覽無遺:
 +  * {{:​study:​apk-decompiler:​250729-001:​pasted:​20250729-151348.png?​500}}
 +===== 總結 =====
 +  * 沒接觸過反編譯的人可能會很驚訝:什麼!要改掉一個 apk 居然這麼簡單!
 +  * 沒錯,就是這麼簡單,而且這只是一個很基本的範例而已。事實上,你想要加入新的程式碼、加入新的資源(圖片、聲音等等)也是可以的。
 +  * 也就是說,你不只可以修改,還可以擴充原本的 apk!
 +  * 但也有些方法可以防止不肖人士反編譯 apk,例如說加殼、混淆、動態載入等,關於這些方法我們下次有機會再介紹給大家囉!
 +===== 延伸閱讀 =====
 +  * 1. [[https://​magiclen.org/​android-decompiler/​|Android 反編譯與防止被反編譯]]
 +  * 2. [[http://​aiur3908.blogspot.tw/​2015/​07/​android-proguard.html|[Android] 程式碼混淆(ProGuard)與反組譯]]
 +  * 3. [[http://​blog.davidou.org/​archives/​553|[Android] 反組譯 破解Android的apk安裝檔]]
 +  * 4. [[http://​www.wangchenlong.org/​2016/​03/​19/​reverse-analyze-apk/​|反编译的常用工具与使用方法]]
 +  * 5. [[http://​blog.csdn.net/​wdaming1986/​article/​details/​8299996|Smali--Dalvik虚拟机指令语言-->​【android_smali语法学习一】]]
 +  * 6. [[http://​blog.isming.me/​2015/​01/​14/​android-decompile-smali/​|android反编译-smali语法]]
 +====== Reference =====
 +  * 
 +====== ======
 +  * {{counter}} person(s) visited this page until now.
 +  * [[:​study:​apk-decompiler:​index|Back]]
 +====== ======
 +<​html>​
 +<​!-- ​
 +PDF for A4-Portrait:​ {{pdfjs 50%,450px > xxx.pdf?​page-fit}}
 +PDF for A4-Landscape:​ {{pdfjs 700px,500px > xxx.pdf?​page-fit}}
 +PDF for iPad Note: {{pdfjs 700px,500px > xxx.pdf?​page-fit}}
 +
 +{{gallery>​work-note:​2024-08:​12?​lightbox&​0&​150x150&​crop}}
 +
 +Youtube: {{youtube>​large:​XXXXX}}
 +Code Highlight: <sxh php; first-line: 70; highlight: [89,92]; title: New title attribute in action>
 +
 +-->
 +</​html>​
study/apk-decompiler/250729-001/index.txt · Last modified: 2025/07/29 15:15 by jethro