android逆向之Dalvik指令集

前言

Dalvik指令語法詳解
該篇文章為本人的學習筆記,如有不對之處,請指教.

附參考鏈接:smali文件語法參考

類型

字節碼類型描述符

語法 含義
V void,只用于返回值類型
Z boolean
B byte
S short
C char
I int
J long
F float
D double
L java類類型
[ 數組類型

其中L類型可以表示Java類型中的任何類.
例如

      java.lang.String  
在smali語法中表示為:
      Ljava.lang.String;

注意后面有個分號,L類型最后的分號表示對象名結束.

[類型可以表示所有基本類型的數組. [后面緊跟基本數據類型描述符. 如[I 相當于Java中的int[],即一維數組. [[I相當于Java中的int[][],即二維數組.
三維、四維等等數值以此類推. 注意多維數組的維數最大為255個.

L[ 可以同時使用用來表示對象數組. 如[Ljava.lang.String;就表示這是一個String類型的數組.

方法及字段

方法的表現格式如下

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

其中 Lpackage/name/ObjectName;應該理解為該方法所在的類,MethodName為具體方法名,(III)Z 這是方法具體的傳參和返回部分,其中括號內的III為方法參數(在這里是表示三個int類型的參數),Z表示方法多維返回值(在這里返回值為boolean類型).

字段的格式和方法很像,只是方法的括號、括號里面的參數及返回值,這些字段都是沒有的,后面取而代之的是字段自己的類型.字段格式如下

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

其中Lpackage/name/ObjectName;不用說還是該字段所在的類,FieldName為字段名,Ljava/lang/String;為字段類型.其中字段名與字段類型之間用冒號:隔開.

Dalvik指令

首先咱們來解析一條指令

move-wide/from16 vAA,vBBBB

move為基礎字節碼,即操作符 . wide為名稱后綴,標識操作的數組為64位. from16位字節碼的后綴,標識源操作數是一個16位寄存器引用變量. vAA為目的寄存器,他始終在源寄存器的前面.
vBBBB為源寄存器. 若沒有wide后綴,默認為32位.

move指令

move 指令的作用是將源寄存器的值賦值給目的寄存器,即

move vA,vB

move-wide作用同上,只是賦值的為64位.</br> move-object是為對象賦值.
move-result 指令的作用是將上一個invoke類型指令的操作結果賦值給目的寄存器,即

move-result vAA

move-result-wide作用同上,只是賦值的為64位. </br> move-object同上,只是賦值為對象類型.

返回指令

return-void表示函數從一個void方法返回.
return 表示函數返回一個32位非對象的值.
return-wide 表示函數返回一個64位非對象的值.
return-object 表示函數返回一個對象類型.

數據定義

const常用來定義程序中用到是常量、字符串、類等數據.</br> const 、const/4、const/16給寄存器賦值基本數據類型.即

const/4 v1, 0x2

const-string給寄存器賦字符串,即

const-string v0, "\u60a8\u7684\u8bd5"

</br>const-class給寄存器賦值一個類引用.

鎖指令

鎖指令用于在多線程程序中對同一對象的操作.

monitor-enter v0

為指定的對象獲取鎖.

monitor-exit v0

釋放指定對象的鎖.

實例操作指令

  • 類型轉換指令
check-cast v0,type@BBBB

v0寄存器轉換成指定的類型.

  • 檢查指令
instance-of v0,v1,type@BBBB

檢測v1是否可以轉換成指定類型,可以轉換v0賦值為1,否則賦值 0.

  • 創建指令
new-instance v0,type@BBBB

構造一個指定類型的實例,并把實例對象的引用賦值給v0.類型符 type指定類型不能為數組.

數組操作指令

  • 創建數組
new-array v0,v1,type@BBBB

構造指定類型的數組,v1表示數組的大小,并將數組賦值給v0.

filed-new-array {v1,v2,v3},type@BBBB

構造數組的另一種方式,即相當于Java中的
int[] arrays= {1,2,3,4};

  • 獲取數組長度
array-length v0,v1

獲取v1寄存器中的數組長度,并賦值給v0寄存器.

跳轉指令

  • goto指令
goto +AA

無條件跳轉到指定偏移量處,偏移量不能為0.

  • switch指令
packed-switch v0,+BBBB

分支跳轉,v0寄存器為switch分支中的判斷值,+BBBB指向的是packed-switch-payload格式的偏移表,表中的值是有規律的.

sparse-switch v0,+BBBB

作用同上,唯一不同是偏移表中的值是無規律的.

  • if指令
    if指令格式如下
    if-eq(此處可替換) v0,v1,+BBBB
    比較兩個寄存器的值,符合條件進行跳轉.
操作符 作用 對應java語句
if-eq 如果v0等于v1則跳轉. if(v0==v1)
if-ne 如果v0不等于v1則跳轉. if(v0!=v1)
if-lt 如果v0小于v1則跳轉. if(v0<v1)
if-gt 如果v0大于v1則跳轉. if(v0>v1)
if-le 如果v0小于等于v1則跳轉. if(v0<=v1)
if-ge 如果v0大于等于v1則跳轉. if(v0>=v1)
    if-eq(此處可替換) v0,+BBBB

用寄存器中的值和0進行比較,符合跳轉跳轉.

操作符 作用 對應java語句
if-eqz 如果v0等于0則跳轉. if(v0==0)
if-nez 如果v0不等于0則跳轉. if(v0!=0)
if-ltz 如果v0小于0則跳轉. if(v0<0)
if-gtz 如果v0大于0則跳轉. if(v0>0)
if-lez 如果v0小于等于0則跳轉. if(v0<=0)
if-gez 如果v0大于等于0則跳轉. if(v0>=0)

比較指令

用于比較兩個寄存器的值(浮點型或長整型),比較結果放到v0寄存器中.
格式

cmpl-float(此處可替換) v0,v1,v2
操作符 作用
cmpl-float 如果v1小于v2則結果為1,相等則結果為0,大于則結果為-1.
cmpg-float 如果v1大于v2則結果為1,相等則結果為0,小于則結果為-1.
cmpl-double 如果v1小于v2則結果為1,相等則結果為0,大于則結果為-1.
cmpg-double 如果v1大于v2則結果為1,相等則結果為0,小于則結果為-1.
cmp-long 如果v1大于v2則結果為1,相等則結果為0,小于則結果為-1.

字段操作指令

字段操作指令分兩大類:普通字段和靜態字段,普通字段指令的前綴為i,靜態字段指令的前綴為s.
字段的讀操作指令為get,寫操作指令為put,因此普通字段的操作指令為iget,iput.靜態字段的操作指令為sget,sput.
指令格式如下

.line 16
iput-object p1, p0, Lcom/view/dialogapplication/PhoneInfo;->context:Landroid/content/Context;

上面是一段iput指令代碼,它所對應的java代碼如下

  this.context = context;

沒錯,它就會一個簡單的賦值context的代碼;
由此,可以看出來, p1是要賦值的context,p0是源,而后面的第三個參數

Lcom/view/dialogapplication/PhoneInfo;->context:Landroid/content/Context;

可以看出來是p1的字段名.

此外還有一組以a為前綴的的操作指令,分別為aputaget,不過它們應該不算在字段的范疇了,應該為數組操作范疇,但因為也是和讀寫操作有關,所以就寫在這里了,具體格式如下

aput-object  v2,v1,v0

其具體作用為將v2的值放入到v1數組的v0位置處.所以可以看出,v2為要放入的值,v1代表著存放v2值的數組,而v0則是v2要存放在數組的位置,即v0為index(數組角標).

方法調用指令

方法調用指令賦值調用類實例(也就是對象)的方法,它的基礎指令為invoke.指令格式如下

invoke-virtual(名稱后綴可替換) {v0,v1},method@BBBB(具體的方法)

其中{v0,v1}大括號中第一位放的是調用方法的對象,之后的為方法中的參數.若沒有參數則只需傳入調用方法的對象,即{v0}.

指令 作用
invoke-virtualinvoke-virtual/range 調用實例的虛方法.
invoke-superinvoke-super/range 調用實例父類的方法.
invoke-directinvoke-direct/range 調用實例的直接方法.
invoke-staticinvoke-static/range 調用實例的靜態方法.
invoke-interfaceinvoke-interface/range 調用實例的接口方法.

數字轉換指令

數據轉換指令用于將一種類型的數值轉換成另一種類型.格式如下

neg-int(可替換如下) v0,v1

指令中,v1存放需要轉換的數據,v0存放轉換后的結果.

指令 作用
neg-int 對整型輸求補.
not-int 對整型輸求反.
neg-long 對長整型數求補.
not-long 對長整型數求反.
neg-float 對單精度浮點型數求補.
neg-double 對雙精度浮點數求補.
int-to-long 將整型數轉換為長整型.
int-to-float 將整型數轉換為單精度浮點型.
int-to-double 將整型數轉換為雙精度浮點型.
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 將整型轉換為短整型.

數據運算指令

數據運算指令分為算術運算指令和邏輯運算指令,即 加、減、乘、除、取模、位移及與、或、非、異或等.
格式如下

add-int(可替換如下) v0,v1,v2

指令中,將v1v2進行運算,結果存到v0.

指令 作用
add-type v1v2進行加法運算,即v1+v2.
sub-type v1v2進行減法運算,即v1-v2.
mul-type v1v2進行乘法運算,即v1*v2.
div-type v1v2進行除法運算,即v1/v2.
rem-type v1v2進行取模運算,即v1%v2.
and-type v1v2進行與運算,即v1 AND v2.
or-type v1v2進行或運算,即v1 OR v2.
xor-type v1v2進行異或運算,即v1 XOR v2.
shl-type v1進行(有符號位)左移v2位,即v1<<v2.
shr-type v1進行(有符號位)右移v2位,即v1>>v2.
ushr-type v1進行(無符號位)右移v2位,即v1>>v2.

其中后面的-type可以是-int、-long、-float、-double.

至此,Dalvik指令集基本就都介紹完了
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容