smali 除錯方法(動態除錯)
smali檔案
1.下圖為基本的smali結構
一個smali檔案對應一個class
2.欄位描述符‘
Java中Void在smali中對應V
Void -> V
其他具體描述符參考下面表格:
下面貼上兩段例子程式碼對應看下:
Android程式碼:
package com.test.myapplication; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.text); tv.setText("hello"); } }
smali程式碼:
.class public Lcom/test/myapplication/MainActivity; .super Landroid/app/Activity; .source "MainActivity.java" # direct methods .method public constructor <init>()V .locals 0 .prologue .line 7 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 11 invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V .line 12 const/high16 v1, 0x7f030000 invoke-virtual {p0, v1}, Lcom/test/myapplication/MainActivity;->setContentView(I)V .line 13 const v1, 0x7f070009 invoke-virtual {p0, v1}, Lcom/test/myapplication/MainActivity;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/widget/TextView; .line 14 .local v0, "tv":Landroid/widget/TextView; const-string v1, "hello" invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V .line 15 return-void .end method
smali頭部分析:
.class public 對應 java class public
Lcom/test/myapplication/MainActivity; 類描述符 L+包+名+; 可檢視上面表中對應 Object —> Ljava/lang/Object;
.super欄位,表示從哪個類中擴展出來的, 此處對應 extends Activity
.source欄位,對應原始檔.source “MainActivity.java”表示java檔案就是MainActivity.java
smali方法分析:
固定格式
.method 開始
.end method 結尾
.method protected onCreate(Landroid/os/Bundle;)V -> protected void onCreate(Bundle savedInstanceState)
Landroid/os/Bundle; 傳入的引數, 最後面的V 表示返回值型別Void
invoke-virtual {p0, v1}, Lcom/test/myapplication/MainActivity;->findViewById(I)Landroid/view/View; -> TextView tv = (TextView) findViewById(R.id.text);
invoke-virtual 呼叫方法
move-result-object v0
把結果放到v0
const-string v1, “hello”
invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
呼叫setText方法,把v1傳入
動態除錯:
工具:apktool
下載地址:https://bitbucket.org/iBotPeaches/apktool/downloads/
注意:此處介紹的動態除錯方法是比較舊的方法,下載2.1.0版本以下的,因為新版本的apktool -d 選項已經移除
反編譯原始碼中新增除錯:
1)java -jar apktool.jar d -d 目標.apk -o 結果放置目錄
2)修改AndroidMainfest檔案,在application節點新增 android:debuggable=”true”
3)在入口類的onCreate方法中新增:
invoke-static{},Landroid/os/Debug;->waitForDebugger()V
新增後示例:
a=0;// .method protected onCreate(Landroid/os/Bundle;)V
a=0;// .locals 2
a=0;// .param p1, "savedInstanceState" # Landroid/os/Bundle;
a=0;//
a=0;// .prologue
a=0;// .line 11
a=0;// invoke-static{},Landroid/os/Debug;->waitForDebugger()V
a=0;// invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
4)回編譯修改過的apk檔案
java -jar apktool.jar b -d 程式碼目錄 -o 目標apk名稱
問題:我在此處用android studio 編譯了一個apk回編譯失敗,暫時沒有解決,直接使用eclipse編譯了一個demo.apk
5)對生成的apk進行簽名,簽名方法可以參照之前的Android反編譯和回編譯文章
使用android studio進行動態除錯:
1)匯入已經反編譯修改好的功能程式碼
開啟Android Studio ->File -> Open -> 選擇剛才反編譯的目錄
2)在相應位置設定斷點
3)設定遠端除錯選項
Run -> Edit Configurations… -> 點選“+” -> Remote -> Host:localhost Port:8700
4)切換到另外一個編寫android程式碼的android studio視窗
開啟Android Device Monitor
點選要除錯的程式的程序
5) 切換到smali工程視窗
點選除錯按鈕,開始除錯
至此就可以像除錯android程式碼一樣除錯smali 程式碼啦