smali語法筆記

資料html

在smali裏的全部操做都必須通過寄存器來進行:

  • 本地寄存器用v開頭數字結尾的符號來表示,如v0、v一、v二、...
  • 參數寄存器則使用p開頭數字結尾的符號來表示,如p0、p一、p二、...
  • p0不必定是函數中的第一個參數,在非static函數中,p0代指「this」,p1表示函數的第一個參數,p2表明函數中的第二個參數…
  • 而在static函數中p0纔對應第一個參數(由於Java的static方法中沒有this方法)

舉例:java

const/4 v0, 0x0  
//使用了v0本地寄存器,並把值0x0存到v0中
iput-boolean v0, p0, Lcom/disney/WMW/WMWActivity;->isRunning:Z 
//用iput-boolean這個指令把v0中的值存放到com.disney.WMW.WMWActivity.isRunning這個成員變量中,至關於:
//this.isRunning = false;在非static函數中p0表明的是「this」,在這裏就是com.disney.WMW.WMWActivity實例

數據類型

  • B---byte
  • C---char
  • D---double
  • F---float
  • I---int
  • J---long
  • S---short
  • V---void
  • Z---boolean
  • [XXX---arrayandroid

    數組:在基本類型前加上前中括號「[」,例如int數組和float數組分別表示爲:[I、[F;數組

  • Lxxx/yyy---objectapp

    對象以L做爲開頭,格式是LpackageName/objectName;(注意必須有個分號跟在最後),例如String對象在smali中爲:Ljava/lang/String;函數

函數的定義

Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Typethis

參數與參數之間沒有任何分隔符
舉例:.net

  • foo ()V 是 void foo()
  • foo (III)Z 是 boolean foo(int, int, int)
  • foo (Z[I[ILjava/lang/String;J)Ljava/lang/String; 是 String foo (boolean, int[], int[], String, long)

內部類 MemberClasses

WMWActivity的內部類 :格式 LpackageName/objectName$subObjectName;。也就是在內部類前加「$」符號code

# annotations
   .annotation system Ldalvik/annotation/MemberClasses;
     value = {
        Lcom/disney/WMW/WMWActivity$MessageHandler;,
        Lcom/disney/WMW/WMWActivity$FinishActivityArgs;
    }
 .end annotation

成員變量

成員變量分靜態與非靜態的,格式是:.field public/private [static] [final] varName: <類型> htm

# static fields
.field private static final PREFS_INSTALLATION_ID:Ljava/lang/String; = "installationId"
# instance fields
 .field private _activityPackageName:Ljava/lang/String;

指令

靜態變量指令以s開頭,非靜態變量(instance)以i開頭

  • 靜態變量的指令:

    獲取指令:sget、sget-boolean、sget-object等
    操做指令: sput、sput-boolean、sput-object等

  • 非靜態變量的指令:

    獲取指令:iget、iget-boolean、iget-object等
    操做指令:iput、iput-boolean、iput-object等

  • 提示:

    沒有「-object」後綴的表示操做的成員變量對象是基本數據類型
    帶「-object」表示操做的成員變量是對象類型
    boolean類型則使用帶「-boolean」的指令操做
    array類型使用aget和aget-object

指令操做舉例

  • 獲取static fields的指令
sget-object v0, Lcom/disney/WMW/WMWActivity;->PREFS_INSTALLATION_ID:Ljava/lang/String;
//獲取PREFS_INSTALLATION_ID這個String類型的值 並並放到v0
  • 獲取instance fields
iget-object v0, p0, Lcom/disney/WMW/WMWActivity;->_view:Lcom/disney/common/WMWView;  
    //v0 將獲取到的值放到v0, p0 是該變量所在類的實例 this
  • put指令
const/4 v3, 0x0  
sput-object v3, Lcom/disney/WMW/WMWActivity;->globalIapHandler:Lcom/disney/config/GlobalPurchaseHandler; 
//至關於:this.globalIapHandler = null;(null = 0x0)
.local v0, wait:Landroid/os/Message;  
const/4 v1, 0x2  
iput v1, v0, Landroid/os/Message;->what:I 
//至關於:wait.what = 0x2;(wait是Message的實例)

smali中的函數調用

兩種類型的方法:

  • direct:是private函數
  • virtual:public和protected函數
    指令:
  • invoke-static 調用static函數的

    invoke-static {}, Lcom/disney/WMW/UnlockHelper;->unlockCrankypack()Z
    {}:是{調用該方法的實例,參數列表}
    const-string v0, "fmodex" invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V //至關於 static void System.loadLibrary("fmodex")

  • invoke-super 調用父類方法用的指令,在onCreate、onDestroy等方法都能看到
  • invoke-direct:調用private函數的
    ```invoke-direct {p0}, Lcom/disney/WMW/WMWActivity;->getGlobalIapHandler()Lcom/disney/config/GlobalPurchaseHandler;
    // getGlobalIapHandler()就是定義在WMWActivity中的一個private函數
* invoke-virtual:用於調用protected或public函數

sget-object v0, Lcom/disney/WMW/WMWActivity;->shareHandler:Landroid/os/Handler;
invoke-virtual {v0, v3}, Landroid/os/Handler;->removeCallbacksAndMessages(Ljava/lang/Object;)V
// v0是shareHandler:Landroid/os/Handler,v3是傳遞給removeCallbackAndMessage方法的Ljava/lang/Object參數
// {v0 是調用的實例,v3是參數}

* invoke-xxxxx/range:當方法的參數多於5個時(含5個),而是在後面加上「/range」

invoke-static/range {v0 .. v5}, Lcn/game189/sms/SMS;->checkFee(Ljava/lang/String;Landroid/app/Activity;Lcn/game189/sms/SMSListener;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
//這裏有點迷惑

### 函數返回值

const/4 v2, 0x0
invoke-virtual {p0, v2}, Lcom/disney/WMW/WMWActivity;->getPreferences(I)Landroid/content/SharedPreferences;
move-result-object v1
v1保存的就是調用getPreferences(int)方法返回的SharedPreferences實例

 

invoke-virtual {v2}, Ljava/lang/String;->length()I
move-result v2
v2保存的則是調用String.length()返回的整型。

###.locals 
.locals 0 表示這個函數中最少要用到的本地寄存器的個數  (參考文章第4點講的挺透徹)

### 條件跳轉分支 [引用](http://www.360doc.com/content/14/1011/10/12917046_416004153.shtml)
* if-eqz v0, :cond_0 意思是 若是v0等於0則跳轉 :cond_0;(eqz:就是equal zero)
* if-nez v0, :cond_0 意思是 若是v0不等於0則跳轉 :cond_0;(nez:就是inequal zero)
* switch:[參考](http://blog.csdn.net/lostinai/article/details/48975661)

.packed-switch 0x0 #case 區域,從0開始,依次遞增 :pswitch_0 #case 0 :pswitch_1 #case 1 :pswitch_2 #case 2 :pswitch_3 #case 3 .end packed-switch pswitch_data_0 爲case 區域,在 case 區域中,第一條指令「.packed-switch」指定了比較的初始值爲0 ,pswitch_0~ pswitch_3分別是比較結果爲「case 0 」到「case 3 」時要跳轉到的地址 ```

相關文章
相關標籤/搜索