1. 程式人生 > >Android安全/安全技術--20--Small組合語言

Android安全/安全技術--20--Small組合語言

========================================================================= Dalvik操作碼詳解: https://download.csdn.net/download/wutianxu123/10699822

=========================================================================

3-1、Smali基礎

1、64位常規型別的位元組碼新增-wide字尾 2、暫存器vAA取值範圍為v0-v255,暫存器vBBBB取值範圍為v0-v65535。其餘同理。 3、每個字母表示4位,每4位之間可用豎線"|"分割來表示不同的內容。 4、類名後有$符號的代表是子類

Dalvik位元組碼型別描述符:

語法 含義
V void,只用於返回值型別
Z boolean,注意和首字母不同
B byte,位元組型
S short,短整型
C char,字元型
I int,整數型
J long,注意和首字母不同。對於64位資料,用兩個暫存器來存放
F float,浮點型
D double,雙精度浮點型
L Java類型別
[ 陣列型別。[I表示一個整型一維陣列,等於int[]。注意多位數陣列的維數最大為255個。[[I=int[][] 、[[[I=int[][][]

類:

Lpackage/name/ObjectName        //L代表Java類型別,後面是類名

方法:

Lpackage/name/ObjectName;->MethodName(引數簽名)返回型別    //類名下的方法名

欄位:

Lpackage/name/ObjectName;->FieldName:型別

3-2、空操作指令

Nop:它的值為00,通常nop指令被用來作對齊程式碼之用,無實際操作。

3-3、資料操作指令

“move vA, vB”:將vB暫存器的值賦給vA暫存器,源暫存器與目的暫存器都為4位。
“move/from16 vAA, vBBBB”:將vBBBB暫存器的值賦給vAA暫存器,源暫存器為16位,目的暫存器為8位。
“move/16 vAAAA, vBBBB”:將vBBBB暫存器的值賦給vAAAA暫存器,源暫存器與目的暫存器都為16位。
“move-wide vA, vB”:為4位的暫存器對賦值。源暫存器與目的暫存器都為4位。
“move-wide/from16 vAA, vBBBB”:與“move-wide/16vAAAA, vBBBB”實現與“move-wide”相同。
“move-object vA, vB”:為物件賦值。源暫存器與目的暫存器都為4位。
“move-object/from16 vAA, vBBBB”:為物件賦值。源暫存器為16位,目的暫存器為8位。
“move-object/16 vAA, vBBBB”:為物件賦值。源暫存器與目的暫存器都為16位。
“move-result vAA”:將上一個invoke型別指令操作的單字非物件結果賦給vAA暫存器。
“move-result-wide vAA”:將上一個invoke型別指令操作的雙字非物件結果賦給vAA暫存器。
“move-result-object vAA":將上一個invoke型別指令操作的物件結果賦給vAA暫存器。
“move-exception vAA”:儲存一個執行時發生的異常到vAA暫存器,這條指令必須是異常發生時的異常處理器的一條指令。否則的話,指令無效。

3-4、返回指令

"return-void":表示函式從一個void方法返回。
“return vAA”:表示函式返回一個32位非物件型別的值,返回值暫存器為8位的暫存器vAA。
“return-wide vAA”:表示函式返回一個64位非物件型別的值,返回值為8位的暫存器對vAA。
“return-object vAA”:表示函式返回一個物件型別的值。返回值為8位的暫存器vAA。

3-5、資料定義指令

“const/4 vA, #+B”:將數值符號擴充套件為32位後賦給暫存器vA。
“const/16 vAA, #+BBBB”:將資料符號擴充套件為32位後賦給暫存器vAA。
“const vAA, #+BBBBBBBB”:將數值賦給暫存器vAA。
“const/high16 vAA, #+BBBB0000“:將數值右邊零擴充套件為32位後賦給暫存器vAA。
“const-wide/16 vAA, #+BBBB”:將數值符號擴充套件為64位後賦給暫存器對vAA。
“const-wide/32 vAA, #+BBBBBBBB”:將數值符號擴充套件為64位後賦給暫存器對vAA。
“const-wide vAA, #+BBBBBBBBBBBBBBBB”:將數值賦給暫存器對vAA。
“const-wide/high16 vAA, #+BBBB000000000000”:將數值右邊零擴充套件為64位後賦給暫存器對vAA。
“const-string vAA, [email protected]”:通過字串索引構造一個字串並賦給暫存器vAA。
“const-string/jumbo vAA, [email protected]”:通過字串索引(較大)構造一個字串並賦給暫存器vAA。
“const-class vAA, [email protected]”:通過型別索引獲取一個類引用並賦給暫存器vAA。
“const-class/jumbo vAAAA, [email protected]”:通過給定的型別索引獲取一個類引用並賦給暫存器vAAAA。

3-6、鎖指令

"monitor-enter vAA":為指定的物件獲取鎖。
“monitor-exit vAA”:釋放指定的物件的鎖。

3-7、例項操作指令

“check-cast vAA, [email protected]”:將vAA暫存器中的物件引用轉換成指定的型別,如果失敗會丟擲ClassCastException異常。如果型別B指定的是基本型別,對於非基本型別的A來說,執行時始終會失敗。
“instance-of vA, vB, [email protected]”:判斷vB暫存器中的物件引用是否可以轉換成指定的型別,如果可以vA暫存器賦值為1,否則vA暫存器賦值為0。
“new-instance vAA, [email protected]”:構造一個指定型別物件的新例項,並將物件引用賦值給vAA暫存器,型別符type指定的型別不能是陣列類。
“check-cast/jumbo vAAAA, [email protected]”:指令功能與第一條相同,只是暫存器值與指令的索引取值範圍更大。
“instance-of/jumbo vAAAA, vBBBB, [email protected]”:指令功能與第二條相同,只是暫存器值與指令的索引取值範圍更大。
“new-instance/jumbo vAAAA, [email protected]”:指令功能與第三條相同只是暫存器值與指令的索引取值範圍更大。

3-8、陣列操作指令

“array-length vA, vB”:獲取給定vB暫存器中陣列長度並將值賦給vA暫存器,陣列長度指的是陣列的條目個數。
“new-array vA, vB, [email protected]”:構造指定型別([email protected])與大小(vB)的陣列,並將值賦給vA暫存器。
“filled-new-array {vC, vD, vE, vF, vG},[email protected]”:構造指定型別([email protected])與大小(vA)的陣列並填充陣列內容。vA暫存器是隱含使用的,除了指定陣列的大小外還指定了引數的個數,vC~vG是使用到的引數寄存序列。
“filled-new-array/range {vCCCC  ..vNNNN}, [email protected]”:指令功能與“filled-new-array {vC, vD, vE, vF, vG}, [email protected]”相同,只是引數暫存器使用range位元組碼字尾指定了取值範圍 ,vC是第一個引數暫存器,N = A +C -1。
"fill-array-data vAA, +BBBBBBBB":用指定的資料來填充陣列,vAA暫存器為陣列引用,引用必須為基礎型別的陣列,在指令後面會緊跟一個數據表。
"new-array/jumbo vAAAA,vBBBB,[email protected]":指令功能與“new-array vA,vB,[email protected]”相同,只是暫存器值與指令的索引取值範圍更大。
"filled-new-array/jumbo{vCCCC  ..vNNNN},[email protected]":指令功能與range{vCCCC  ..vNNNN},[email protected]相同,只是索引取值範圍更大。
"arrayop vAA, vBB, vCC":對vBB暫存器指定的陣列元素進入取值與賦值。vCC暫存器指定陣列元素索引,vAA暫存器用來存放讀取的或需要設定的陣列元素的值。

3-9、異常指令

“throw vAA”:丟擲vAA暫存器中指定型別的異常。

3-10、跳轉指令

“goto +AA”:無條件跳轉到指定偏移處,偏移量AA不能為0。
“goto/16 +AAAA”:無條件跳轉到指定偏移處,偏量AAAA不能為0。
“goto/32 +AAAAAAAA”:無條件跳轉到指定偏移處。
“packed-switch vAA, +BBBBBBBB”:分支跳轉指令。vAA暫存器為switch分支中需要判斷的值,BBBBBBBB指向一個packed-switch-payload格式的偏移表,表中的值是有規律遞增的。
“sparse-switch vAA, +BBBBBBBB”:分支跳轉指令。vAA暫存器為switch分支中需要判斷的值,BBBBBBBB指向一個sparse-switch-payload格式的偏移表,表中的值是無規律的偏移量。
“if-eq”:如果vA等於vB則跳轉。Java語法表示為“if(vA== vB)”
"if-ne":如果vA不等於vB則跳轉。Java語法表示為“if(vA!= vB)”
“if-lt”:如果vA小於vB則跳轉。Java語法表示為“if(vA< vB)”
“if-ge”:如果vA大於等於vB則跳轉。Java語法表示為“if(vA>= vB)”
“if-gt”:如果vA大於vB則跳轉。Java語法表示為“if(vA> vB)”
“if-le”:如果vA小於等於vB則跳轉。Java語法表示為“if(vA<= vB)”
“if-eqz”:如果vAA為0則跳轉。Java語法表示為“if(vAA== 0)”
"if-nez":如果vAA不為0則跳轉。Java語法表示為“if(vAA!= 0)”
"if-ltz":如果vAA小於0則跳轉。Java語法表示為“if(vAA< 0)”
“if-gez”:如果vAA大於等於0則跳轉。Java語法表示為“if(vAA>= 0)”
“if-gtz”:如果vAA大於0則跳轉。Java語法表示為“if(vAA> 0)”
“if-lez”:如果vAA小於等於0則跳轉。Java語法表示為“if(vAA<= 0)”

3-11、比較指令

“cmpl-float”:比較兩個單精度浮點數。如果vBB暫存器大於vCC暫存器,結果為-1,相等結果為0,小於結果為1
“cmpg-float”:比較兩個單精度浮點數。如果vBB暫存器大於vCC暫存器,結果為1,相等結果為0,小於結果為-1
“cmpl-double”:比較兩個雙精度浮點數。如果vBB暫存器對大於vCC暫存器對,結果為-1,相等為0,小於為1
“cmpg-double”:比較兩個雙精度浮點數。如果vBB暫存器對大於vCC暫存器對,結果為1,相等為0,小於為-1
“cmp-long”:比較兩個長整型數。如果vBB暫存器大於vCC暫存器,結果為1,相等結果為0,小結果為-1

3-12、方法呼叫指令

“invoke-virtual” 或 “invoke-virtual/range”:呼叫例項的虛方法。
“invoke-super”或"invoke-super/range":呼叫例項的父類方法。
“invoke-direct”或“invoke-direct/range”:呼叫例項的直接方法。
“invoke-static”或“invoke-static/range”:呼叫例項的靜態方法。
“invoke-interface”或“invoke-interface/range”:呼叫例項的介面方法。

3-13、資料轉換指令

“neg-int”:對整型數求補。
“not-int”:對整型數求反。
“neg-long”:對長整型數求補。
“not-long”:對長整型數求反。
“neg-float”:對單精度浮點型數求補。
“neg-double”:對雙精度浮點型數求補。
“int-to-long”:將整型數轉換為長整型。
“int-to-float”:將整型數轉換為單精度浮點型數。
“int-to-dobule”:將整型數轉換為雙精度浮點數。
“long-to-int”:將長整型數轉換為整型。
“long-to-float”:將長整型數轉換為單精度浮點型。
“long-to-double”:將長整型數轉換為雙精度浮點型。
“float-to-int”:將單精度浮點數轉換為整型。
“float-to-long”:將單精度浮點數轉換為長整型數。
“float-to-double”:將單精度浮點數轉換為雙精度浮點型數。
“double-to-int”:將雙精度浮點數轉換為整型。
“double-to-long”:將雙精度浮點數轉換為長整型。
“double-to-float”:將雙精度浮點數轉換為單精度浮點型。
“int-to-byte”:將整型轉換為位元組型。
“int-to-char”:將整型轉換為字元型。
“int-to-short”:將整型轉換為短整型。

3-14、資料執行指令

“add-type”:vBB暫存器與vCC暫存器值進行加法運算(vBB + vCC)
"sub-type":vBB暫存器與vCC暫存器值進行減法運算(vBB - vCC)
"mul-type":vBB暫存器與vCC暫存器值進行乘法運算(vBB * vCC)
"div-type":vBB暫存器與vCC暫存器值進行除法運算(vBB / vCC)
"rem-type":vBB暫存器與vCC暫存器值進行模運算(vBB % vCC)
"and-type":vBB暫存器與vCC暫存器值進行與運算(vBB & vCC)
"or-type":vBB暫存器與vCC暫存器值進行或運算(vBB | vCC)
"xor-type":vBB暫存器與vCC暫存器值進行異或運算(vBB ^ vCC)
"shl-type":vBB暫存器值(有符號數)左移vCC位(vBB << vCC )
"shr-type":vBB暫存器值(有符號)右移vCC位(vBB >> vCC)
"ushr-type":vBB暫存器值(無符號數)右移vCC位(vBB >>> vCC)

其中基礎位元組碼後面的-type可以是-int,-long, -float,-double。後面3類指令與之類似。