Smail語法基本知識(一)

Smali 背景:

 Smali,是指安卓系統裏的 Java 虛擬機(Dalvik)所使用的一種.dex 格式文件的彙編器。

 Baksmali 則是反彙編器。

 其語法是一種寬鬆式的 Jasmin/dedexer語法,而且它實現了.dex 格式所有功能(註解,調試信息,線路信息等)。

 Smali,Baksmali 分別是冰島語中編譯器,反編譯器的叫法。


Smali 語法簡單介紹如下:

類型

Davlik 字節碼中,寄存器都是 32 位的,

所以64 位類型(Long/Double)需要用 2 個寄存器表示。

Dalvik 字節碼有兩種類型:原始類型和引用類型(包括對象和數組)

原始類型

V     void            只能用於返回值類型

Z     boolean

B    byte

S    short

C    char

I      int

J     long(64 位)

F     float

D    double(64 位)

說明:只有boolean和long不同,因爲他們和byte,int的首字符一樣,所以換了一個字符表示。

對象類型

使用L來表示對象。

Lpackage/name/ObjectName; 

相當於 java 中的package.name.ObjectName;

其中:

L                             表示這是一個對象類型

package/name       該對象所在的包

ObjectName           對象名

;                             表示對象名稱的結束


數組表示

使用[ 來表示數組。

[I :表示一個整形的一維數組,相當於 java 的 int[];

對於多維數組,只要增加[ 就行了,[[I = int[][];

注:每一維最多 255 個;

例如:

[Ljava/lang/String 表示一個 String 的對象數組;

也就是Java代碼中的字符串數組:  java.lang.String[]


方法表示

Lpackage/name/ObjectName;->methodName(III)Z 


Lpackage/name/ObjectName   表示是哪個類

methodName                            表示方法名

III                                              表示參數(這裏表示爲 3 個整型參數,因爲整形是I)

Z                                               返回值,這裏是boolean

說明:方法的參數是一個接一個的,中間沒有隔開。


成員變量表示

Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;

即表示: 包名(package.name),成員變量名(ObjectName)和各成員變量類型(java.lang.String)

有兩種方式指定一個方法中有多少寄存器是可用的

.registers 指令指定了方法中寄存器的總數

.locals 指令表明了方法中非參寄存器的總數,出現在方法中的第一行

例如:

.method private static a(Ljava/io/File;)V
    .locals 3 //表明有3個非參數寄存器 v0,v1,v2


方法的傳參

當一個方法被調用的時候,方法的參數被置於最後 N 個寄存器中;
例如,一個方法有 2 個參數,5 個寄存器(v0~v4)
那麼,參數將置於最後 2 個寄存器(v3 和 v4)
非靜態方法中的第一個參數總是調用該方法的對象;

說明:對於靜態方法除了沒有隱含的 this 參數外,其他都一樣。

可以這樣理解 reg = local + para(詳細解析見下段)


寄存器的命名方式

有兩種方式——V命名方式和P命名方式。

P命名方式中的第一個寄存器就是方法中的第一個參數寄存器。

在下表中我們用這兩種命名方式來表示上一個例子中有5個寄存器和3個參數的方法。
  v0 第一個local register
  v1 第二個local register
  v2 p0 第一個parameter register
  v3 p1 第二個parameter register
  v4 p2 第三個parameter register
  你可以用任何一種方式來引用參數寄存器——他們沒有任何差別。

使用 P 命名是爲了防止以後如果在方法中增加寄存器,需要對參數寄存器重新進行編號的缺點


特別說明一下:Long 和 Double 類型是 64 位的,需要 2 個寄存器

例如:對於非靜態方法
LMyObject——>myMethod(IJZ)V;
有 4 個參數:LMyObject,int,long,bool; 需要 5 個寄存器來存儲參數;
P0 this
P1 I (int)
P2,P3 J (long)
P4 Z(bool)

標記

  static fields             定義靜態變量的標記

  # instance fields        定義實例變量的標記

  # direct methods       定義靜態方法的標記

  # virtual methods      定義非靜態方法的標記

參考資料如下:

概要:http://wenku.baidu.com/view/2ac1725e8e9951e79b8927df.html

寄存器P,V命名方式:http://blog.sina.com.cn/s/blog_65380c300101dn8f.html

smali 語法:http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
發佈了34 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章