-
Smali就是Dalvik VM內部執行的核心代碼,是一種Dalvik的自己的語法規范。
smali的數據類型:
- B---byte
- C---char
- D---double
- F---float
- I---int
- J---long
- S---short
- V---void
- Z---boolean
- [XXX---array
- Lxxx/yyy---object (Landroid/app/Activity)
- 這里解析下最后兩項,數組的表示方式是:在基本類型前加上前中括號“[”,例如int數組和float數組分別表示為:[I、[F;對象的表示則以L作為開頭,格式是LpackageName/objectName;(注意必須有個分號跟在最后),例如String對象在smali中為:Ljava/lang/String;,其中java/lang對應java.lang包,String就是定義在該包中的一個對象。
- 內部類:LpackageName/objectName$subObjectName;。也就是在內部類前加“$”符號。
函數的定義:
Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type
注意參數與參數之間沒有任何分隔符,同樣舉幾個例子就容易明白了:
1. foo ()V
void foo()。
2. foo (III)Z
boolean foo(int, int, int)。
3. foo (Z[I[ILjava/lang/String;J)Ljava/lang/String;
String foo (boolean, int[], int[], String, long)
4. foo ([Ljava/lang/String)Ljava/lang/String;
String foo (String [])
5. foo(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
String method(int, int[][], int, String, Object[])
寄存器:
- 對於一個使用m個寄存器(m=局部變量寄存器個數l+參數寄存器個數n)的方法而言,局部寄存器使用從v0開始的l個寄存器,而參數寄存器則使用最后的n個寄存器.舉個例子說明假設實例方法test(String a,String b)一共使用了5個寄存器:0,1,2,3,4,那么參數寄存器是能使用2,3,4這三個寄存器,如圖
寄存器的命名
寄存器有兩種不同的命名方法:v字命名法和p字命 名法.這兩種命名法僅僅是影響了字節碼的可讀性.
v字命名法
以小寫字母v開頭的方式表示方法中使用的局部變量和參數.
- 對於上面實例方法test(String a,String b)來說,v0,v1為局部變量能夠使用的寄存器,v2,v3,v4為參數能夠使用的寄存器:
p字命名法
以小寫字母p開頭的方式表示參數,參數名稱從p0開始,依次增大.局部變量能夠使用的寄存器仍然是以v開頭.
- 總之不管是P還是V命名法,參數在后,局部變量在前。
指令:
數據定義指令
- 數據定義指令用於定義代碼中使用的常量,類等數據,基礎指令是const
指令 描述 const/4 vA,#+B 將數值符號擴展為32后賦值給寄存器vA const-wide/16 vAA,#+BBBB 將數值符號擴展為64位后賦值個寄存器對vAA const-string vAA,string@BBBB 通過字符串索引高走字符串賦值給寄存器vAA const-class vAA,type@BBBB 通過類型索引獲取一個類的引用賦值給寄存器vAA
數據操作指令
- move指令用於數據操作,其表示move destination,source,即數據數據從source寄存器(源寄存器)移動到destionation寄存器(源寄存器),可以理解java中變量間的賦值操作.根據字節碼和類型的不同,move指令后會跟上不同的后綴.
指令 描述 move vA,vB 將vB寄存器的值賦值給vA寄存器,vA和vB寄存器都是4位 move/from16 vAA,VBBBB 將vBBBB寄存器(16位)的值賦值給vAA寄存器(7位),from16表示源寄存器vBBBB是16位的 move/16 vAAAA,vBBBB 將寄存器vBBBB的值賦值給vAAAA寄存器,16表示源寄存器vBBBB和目標寄存器vAAAA都是16位 move-object vA,vB 將vB寄存器中的對象引用賦值給vA寄存器,vA寄存器和vB寄存器都是4位 move-result vAA 將上一個invoke指令(方法調用)操作的單字(32位)非對象結果賦值給vAA寄存器 move-result-wide vAA 將上一個invoke指令操作的雙字(64位)非對象結果賦值給vAA寄存器 mvoe-result-object vAA 將上一個invoke指令操作的對象結果賦值給vAA寄存器 move-exception vAA 保存上一個運行時發生的異常到vAA寄存器
對象操作指令
- 與對象實例相關的操作,比如對象創建,對象檢查等.
指令 描述 new-instance vAA,type@BBBB構造一個指定類型的對象將器引用賦值給vAA寄存器.此處不包含數組對象 instance-of vA,vB,type@CCCC判斷vB寄存器中對象的引用是否是指定類型,如果是,將v1賦值為1,否則賦值為0 check-cast vAA,type@BBBB將vAA寄存器中對象的引用轉成指定類型,成功則將結果賦值給vAA,否則拋出ClassCastException異常.
數組操作指令
- 在實例操作指令中我們並沒有發現創建對象的指令.Davilk中設置專門的指令用於數組操作.
指令 說明 new-array vA,vB,type@CCCC 創建指定類型與指定大小(vB寄存器指定)的數組,並將其賦值給vA寄存器 fill-array-data vAA,+BBBBBBBB 用指定的數據填充數組,vAA代表數組的引用(數組的第一個元素的地址)
數據運算指令
- 數據運算主要包括兩種:算數運算和邏輯運算.
1. 算術運算指令
指令 說明 add-type 加法指令 sub-type 減法指令 mul-type 乘法指令 div-type 除法指令 rem-type 求 2. 邏輯元算指令
指令 說明 and-type 與運算指令 or-type 或運算指令 xor-type 異或元算指令 3. 位移指令
指令 說明 shl-type 有符號左移指令 shr-type 有符號右移指令 ushr-type 無符號右移指令 上面的-type表示操作的寄存器中數據的類型,可以是-int,-float,-long,-double等.
比較指令
- 比較指令用於比較兩個寄存器中值的大小,其基本格式格式是
cmp+kind-type vAA,vBB,vCC,type表示比較數據的類型,如-long,-float等;kind則代表操作類型,因此有cmpl,cmpg,cmp三種比較指令.coml是compare less的縮寫,cmpg是compare greater的縮寫,因此cmpl表示vBB小於vCC中的值這個條件是否成立,是則返回1,否則返回-1,相等返回0;cmpg表示vBB大於vCC中的值這個條件是否成立,是則返回1,否則返回-1,相等返回0.
cmp和cmpg的語意一致,即表示vBB大於vCC寄存器中的值是否成立,成立則返回1,否則返回-1,相等返回0
來具體看看Davilk中的指令:
指令 說明 cmpl-float vAA,vBB,vCC比較兩個單精度的浮點數.如果vBB寄存器中的值大於vCC寄存器的值,則返回-1到vAA中,相等則返回0,小於返回1 cmpg-float vAA,vBB,vCC比較兩個單精度的浮點數,如果vBB寄存器中的值大於vCC的值,則返回1,相等返回0,小於返回-1 cmpl-double vAA,vBB,vCC比較兩個雙精度浮點數,如果vBB寄存器中的值大於vCC的值,則返回-1,相等返回0,小於則返回1 cmpg-double vAA,vBB,vCC比較雙精度浮點數,和cmpl-float的語意一致 cmp-double vAA,vBB,vCC等價與cmpg-double vAA,vBB,vCC指令
字段操作指令
- 字段操作指令表示對對象字段進行設值和取值操作,就像是你在代碼中長些的set和get方法.基本指令是iput-type,iget-type,sput-type,sget-type.type表示數據類型.
普通字段讀寫操作
前綴是i的iput-type和iget-type指令用於字段的讀寫操作.
靜態字段讀寫操作
前綴是s的sput-type和sget-type指令用於靜態字段的讀寫操作
指令 說明 sget-byte vX,vY,filed_id sput-byte vX,vY,filed_id sget-boolean vX,vY,filed_id sput-boolean vX,vY,filed_id sget-long vX,vY,filed_id sput-long vX,vY,filed_id
方法調用指令
Davilk中的方法指令和JVM的中指令大部分非常類似.目前共有五條指令集:
指令 說明 invoke-direct{parameters},methodtocall調用實例的直接方法,即private修飾的方法.此時需要注意{}中的第一個元素代表的是當前實例對象,即this,后面接下來的才是真正的參數.比如指令invoke-virtual {v3,v1,v4},Test2.method5:(II)V中,v3表示Test2當前實例對象,而v1,v4才是方法參數 invoke-static{parameters},methodtocall調用實例的靜態方法,此時{}中的都是方法參數 invoke-super{parameters},methodtocall調用父類方法 invoke-virtual{parameters},methodtocall調用實例的虛方法,即public和protected修飾修飾的方法 invoke-interface{parameters},methodtocall調用接口方法 這五種指令是基本指令,除此之外,你也會遇到invoke-direct/range,invoke-static/range,invoke-super/range,invoke-virtual/range,invoke-interface/range指令,該類型指令和以上指令唯一的區別就是后者可以設置方法參數可以使用的寄存器的范圍,在參數多於四個時候使用.
再此強調一遍對於非靜態方法而言{}的結構是{當前實例對象,參數1,參數2,…參數n},而對於靜態方法而言則是{參數1,參數2,…參數n}
需要注意,如果要獲取方法執行有返回值,需要通過上面說道的move-result指令獲取執行結果.
方法返回指令
- 在java中,很多情況下我們需要通過Return返回方法的執行結果,在Davilk中同樣提供的return指令來返回運行結果:
指令 說明 return-void 什么也不返回 return vAA 返回一個32位非對象類型的值 return-wide vAA 返回一個64位非對象類型的值 return-object vAA 反會一個對象類型的引用
同步指令
- 同步一段指令序列通常是由java中的synchronized語句塊表示,則JVM中是通過monitorenter和monitorexit的指令來支持synchronized關鍵字的語義的,而在Davilk中同樣提供了兩條類似的指令來支持synchronized語義:
指令 說明 monitor-enter vAA 為指定對象獲取鎖操作 monitor-exit vAA 為指定對象釋放鎖操作
異常指令
- 很久以前,VM也是用過jsr和ret指令來實現異常的,但是現在的JVM中已經拋出原先的做法,轉而采用異常表來實現異常.而Davilk仍然使用指令來實現:
指令 說明 throw vAA 拋出vAA寄存器中指定類型的異常
跳轉指令
- 跳轉指令用於從當前地址條狀到指定的偏移處,在if,switch分支中使用的居多.Davilk中提供了goto,packed-switch,if-test指令用於實現跳轉操作
指令 操作 goto +AA無條件跳轉到指定偏移處(AA即偏移量) packed-switch vAA,+BBBBBBBB分支跳轉指令.vAA寄存器中的值是switch分支中需要判斷的,BBBBBBBB則是偏移表(packed-switch-payload)中的索引值, spare-switch vAA,+BBBBBBBB分支跳轉指令,和packed-switch類似,只不過BBBBBBBB偏移表(spare-switch-payload)中的索引值 if-test vA,vB,+CCCC條件跳轉指令,用於比較vA和vB寄存器中的值,如果條件滿足則跳轉到指定偏移處(CCCC即偏移量),test代表比較規則,可以是eq.lt等.
- 在條件比較中,if-test中的test表示比較規則.該指令用的非常多,因此我們簡單的坐下說明:
指令 說明 if-eq vA,vB,targetvA,vB寄存器中的相等,等價於java中的if(a==b),比如if-eq v3,v10,002c表示如果條件成立,則跳轉到current position+002c處.其余的類似 if-ne vA,vB,target等價與java中的if(a!=b) if-lt vA,vB,targetvA寄存器中的值小於vB,等價於java中的if(a <b)if-gt vA,vB,target等價於java中的if(a >b)if-ge vA,vB,target等價於java中的if(a >=b)if-le vA,vB,target等價於java中的if(a <=b)
- 除了以上指令之外,Davilk還提供可一個零值條件指令,該指令用於和0比較,可以理解為將上面指令中的vB寄存器的值固定為0.
指令 說明 if-eqz vAA,target 等價於java中的if(a==0)或者if(!a) if-nez vAA,target 等價於java中的if(a!=0)或者if(a) if-ltz vAA,target 等價於java中的if(a <0)if-gtz vAA,target 等價於java中的if(a >0)if-lez vAA,target 等價於java中的if(a <=0)if-gtz vAA,target 等價於java中的if(a >=0)附:
上面我們說道兩張偏移表packed-switch-payload和spare-switch-payload,兩者唯一的區別就是表中的值是否有序,后面我們會在下文中進行詳細的說明.
數據轉換指令
數據類型轉換對任何java開發者都是非常熟悉的,用於實現兩種不同數據類型的相互轉換.其基本指令格式是:unop vA,vB,表示對vB寄存器的中值進行操作,並將結果保存在vA寄存器中.
指令 說明 int-to-long 整形轉為長整型 float-to-int 單精度浮點型轉為整形 int-to-byte 整形轉為字節類型 neg-int 求補指令,對整數求補 not-int 求反指令,對整數求反 結合下表的指令大全:
Opcode (hex) Opcode name Explanation Example 00 nop No operation 0000 - nop 01 move vx,vy Moves the content of vy into vx. Both registers must be in the first 256 register range. 0110 - move v0, v1
Moves v1 into v0.02 move/from16 vx,vy Moves the content of vy into vx. vy may be in the 64k register range while vx is one of the first 256 registers. 0200 1900 - move/from16 v0, v25
Moves v25 into v0.03 move/16 04 move-wide 05 move-wide/from16 vx,vy Moves a long/double value from vy to vx. vy may be in the 64k register range while wx is one of the first 256 registers. 0516 0000 - move-wide/from16 v22, v0
Moves v0 into v22.06 move-wide/16 07 move-object vx,vy Moves the object reference from vy to vx. 0781 - move-object v1, v8
Moves the object reference in v8 to v1.08 move-object/from16 vx,vy Moves the object reference from vy to vx, vy can address 64k registers and vx can address 256 registers. 0801 1500 - move-object/from16 v1, v21
Move the object reference in v21 to v1.09 move-object/16 0A move-result vx Move the result value of the previous method invocation into vx. 0A00 - move-result v0
Move the return value of a previous method invocation into v0.0B move-result-wide vx Move the long/double result value of the previous method invocation into vx,vx+1. 0B02 - move-result-wide v2
Move the long/double result value of the previous method invocation into v2,v3.0C move-result-object vx Move the result object reference of the previous method invocation into vx. 0C00 - move-result-object v0 0D move-exception vx Move the exception object reference thrown during a method invocation into vx. 0D19 - move-exception v25 0E return-void Return without a return value 0E00 - return-void 0F return vx Return with vx return value 0F00 - return v0
Returns with return value in v0.10 return-wide vx Return with double/long result in vx,vx+1. 1000 - return-wide v0
Returns with a double/long value in v0,v1.11 return-object vx Return with vx object reference value. 1100 - return-object v0
Returns with object reference value in v012 const/4 vx,lit4 Puts the 4 bit constant into vx 1221 - const/4 v1, #int2
Moves literal 2 into v1. The destination register is in the lower 4 bit in the second byte, the literal 2 is in the higher 4 bit.13 const/16 vx,lit16 Puts the 16 bit constant into vx 1300 0A00 - const/16 v0, #int 10
Puts the literal constant of 10 into v0.14 const vx, lit32 Puts the integer constant into vx 1400 4E61 BC00 - const v0, #12345678 // #00BC614E
Moves literal 12345678 into v0.15 const/high16 v0, lit16 Puts the 16 bit constant into the topmost bits of the register. Used to initialize float values. 1500 2041 - const/high16 v0, #float 10.0 // #41200000
Moves the floating literal of 10.0 into v0. The 16 bit literal in the instruction carries the top 16 bits of the floating point number.16 const-wide/16 vx, lit16 Puts the integer constant into vx and vx+1 registers, expanding the integer constant into a long constant.. 1600 0A00 - const-wide/16 v0, #long 10
Moves literal 10 into v0 and v1 registers.17 const-wide/32 vx, lit32 Puts the 32 bit constant into vx and vx+1 registers, expanding the integer constant into a long constant. 1702 4e61 bc00 - const-wide/32 v2, #long 12345678 // #00bc614e
Puts #12345678 into v2 and v3 registers.18 const-wide vx, lit64 Puts the 64 bit constant into vx and vx+1 registers. 1802 874b 6b5d 54dc 2b00- const-wide v2, #long 12345678901234567 // #002bdc545d6b4b87
Puts #12345678901234567 into v2 and v3 registers.19 const-wide/high16 vx,lit16 Puts the 16 bit constant into the highest 16 bit of vx and vx+1 registers. Used to initialize double values. 1900 2440 - const-wide/high16 v0, #double 10.0 // #402400000
Puts the double constant of 10.0 into v0 register.1A const-string vx,string_id Puts reference to a string constant identified by string_id into vx. 1A08 0000 - const-string v8, "" // string@0000
Puts reference to string@0000 (entry #0 in the string table) into v8.1B const-string-jumbo 1C const-class vx,type_id Moves the class object of a class identified by type_id (e.g. Object.class) into vx. 1C00 0100 - const-class v0, Test3 // type@0001
Moves reference to Test3.class (entry#1 in the type id table) into1D monitor-enter vx Obtains the monitor of the object referenced by vx. 1D03 - monitor-enter v3
Obtains the monitor of the object referenced by v3.1E monitor-exit Releases the monitor of the object referenced by vx. 1E03 - monitor-exit v3
Releases the monitor of the object referenced by v3.1F check-cast vx, type_id Checks whether the object reference in vx can be cast to an instance of a class referenced by type_id. Throws ClassCastException if the cast is not possible, continues execution otherwise. 1F04 0100 - check-cast v4, Test3 // type@0001
Checks whether the object reference in v4 can be cast to type@0001 (entry #1 in the type id table)20 instance-of vx,vy,type_id Checks whether vy is instance of a class identified by type_id. Sets vx non-zero if it is, 0 otherwise. 2040 0100 - instance-of v0, v4, Test3 // type@0001
Checks whether the object reference in v4 is an instance of type@0001 (entry #1 in the type id table). Sets v0 to non-zero if v4 is instance of Test3, 0 otherwise.21 array-length vx,vy Calculates the number of elements of the array referenced by vy and puts the length value into vx. 2111 - array-length v1, v1
Calculates the number of elements of the array referenced by v1 and puts the result into v1.22 new-instance vx,type Instantiates an object type and puts the reference of the newly created instance into vx. 2200 1500 - new-instance v0, java.io.FileInputStream // type@0015
Instantiates type@0015 (entry #15H in the type table) and puts its reference into v0.23 new-array vx,vy,type_id Generates a new array of type_id type and vy element size and puts the reference to the array into vx. 2312 2500 - new-array v2, v1, char[] // type@0025
Generates a new array of type@0025 type and v1 size and puts the reference to the new array into v2.24 filled-new-array {parameters},type_id Generates a new array of type_id and fills it with the parameters5. Reference to the newly generated array can be obtained by a move-result-object instruction, immediately following the filled-new-array instruction. 2420 530D 0000 - filled-new-array {v0,v0},[I // type@0D53
Generates a new array of type@0D53. The array's size will be 2 and both elements will be filled with the contents of v0 register.25 filled-new-array-range {vx..vy},type_id Generates a new array of type_id and fills it with a range of parameters. Reference to the newly generated array can be obtained by a move-result-object instruction, immediately following the filled-new-array instruction. 2503 0600 1300 - filled-new-array/range {v19..v21}, [B // type@0006
Generates a new array of type@0D53. The array's size will be 3 and the elements will be filled using the v19,v20 and v21 registers4.26 fill-array-data vx,array_data_offset Fills the array referenced by vx with the static data. The location of the static data is the sum of the position of the current instruction and the offset 2606 2500 0000 - fill-array-data v6, 00e6 // +0025
Fills the array referenced by v0 with the static data at current instruction+25H words location. The offset is expressed as a 32-bit number. The static data is stored in the following format:
0003 // Table type: static array data
0400 // Byte per array element (in this case, 4 byte integers)
0300 0000 // Number of elements in the table
0100 0000 // Element #0: integer 1
0200 0000 // Element #1: integer 2
0300 0000 // Element #2: integer327 throw vx Throws an exception object. The reference of the exception object is in vx. 2700 - throw v0
Throws an exception. The exception object reference is in v0.28 goto target Unconditional jump by short offset2. 28F0 - goto 0005 // -0010
Jumps to current position-16 words (hex 10). 0005 is the label of the target instruction.29 goto/16 target Unconditional jump by 16 bit offset2. 2900 0FFE - goto/16 002f // -01f1
Jumps to the current position-1F1H words. 002F is the label of the target instruction.2A goto/32 target 2B packed-switch vx,table Implements a switch statement where the case constants are close to each other. The instruction uses an index table. vx indexes into this table to find the offset of the instruction for a particular case. If vx falls out of the index table, the execution continues on the next instruction (default case). 2B02 0C00 0000 - packed-switch v2, 000c // +000c
Execute a packed switch according to the switch argument in v2. The position of the index table is at current instruction+0CH words. The table looks like the following:
0001 // Table type: packed switch table
0300 // number of elements
0000 0000 // element base
0500 0000 0: 00000005 // case 0: +00000005
0700 0000 1: 00000007 // case 1: +00000007
0900 0000 2: 00000009 // case 2: +000000092C sparse-switch vx,table Implements a switch statement with sparse case table. The instruction uses a lookup table with case constants and offsets for each case constant. If there is no match in the table, execution continues on the next instruction (default case). 2C02 0c00 0000 - sparse-switch v2, 000c // +000c
Execute a sparse switch according to the switch argument in v2. The position of the lookup table is at current instruction+0CH words. The table looks like the following.
0002 // Table type: sparse switch table
0300 // number of elements
9cff ffff // first case: -100
fa00 0000 // second case constant: 250
e803 0000 // third case constant: 1000
0500 0000 // offset for the first case constant: +5
0700 0000 // offset for the second case constant: +7
0900 0000 // offset for the third case constant: +92D cmpl-float Compares the float values in vy and vz and sets the integer value in vx accordingly3 2D00 0607 - cmpl-float v0, v6, v7
Compares the float values in v6 and v7 then sets v0 accordingly. NaN bias is less-than, the instruction will return -1 if any of the parameters is NaN.2E cmpg-float vx, vy, vz Compares the float values in vy and vz and sets the integer value in vx accordingly3. 2E00 0607 - cmpg-float v0, v6, v7
Compares the float values in v6 and v7 then sets v0 accordingly. NaN bias is greater-than, the instruction will return 1 if any of the parameters is NaN.2F cmpl-double vx,vy,vz Compares the double values in vy and vz2 and sets the integer value in vx accordingly3. 2F19 0608 - cmpl-double v25, v6, v8
Compares the double values in v6,v7 and v8,v9 and sets v25 accordingly. NaN bias is less-than, the instruction will return -1 if any of the parameters is NaN.30 cmpg-double vx, vy, vz Compares the double values in vy and vz2 and sets the integer value in vx accordingly3. 3000 080A - cmpg-double v0, v8, v10
Compares the double values in v8,v9 and v10,v11 then sets v0 accordingly. NaN bias is greater-than, the instruction will return 1 if any of the parameters is NaN.31 cmp-long vx, vy, vz Compares the long values in vy and vz and sets the integer value in vx accordingly3. 3100 0204 - cmp-long v0, v2, v4
Compares the long values in v2 and v4 then sets v0 accordingly.32 if-eq vx,vy,target Jumps to target if vx==vy2. vx and vy are integer values. 32b3 6600 - if-eq v3, v11, 0080 // +0066
Jumps to the current position+66H words if v3==v11. 0080 is the label of the target instruction.33 if-ne vx,vy,target Jumps to target if vx!=vy2. vx and vy are integer values. 33A3 1000 - if-ne v3, v10, 002c // +0010
Jumps to the current position+10H words if v3!=v10. 002c is the label of the target instruction.34 if-lt vx,vy,target Jumps to target is vx<vy2. vx and vy are integer values. 3432 CBFF - if-lt v2, v3, 0023 // -0035
Jumps to the current position-35H words if v2<v3. 0023 is the label of the target instruction.35 if-ge vx, vy,target Jumps to target if vx>=vy2. vx and vy are integer values. 3510 1B00 - if-ge v0, v1, 002b // +001b
Jumps to the current position+1BH words if v0>=v1. 002b is the label of the target instruction.36 if-gt vx,vy,target Jumps to target if vx>vy2. vx and vy are integer values. 3610 1B00 - if-ge v0, v1, 002b // +001b
Jumps to the current position+1BH words if v0>v1. 002b is the label of the target instruction.37 if-le vx,vy,target Jumps to target if vx<=vy2. vx and vy are integer values. 3756 0B00 - if-le v6, v5, 0144 // +000b
Jumps to the current position+0BH words if v6<=v5. 0144 is the label of the target instruction.38 if-eqz vx,target Jumps to target if vx==02. vx is an integer value. 3802 1900 - if-eqz v2, 0038 // +0019
Jumps to the current position+19H words if v2==0. 0038 is the label of the target instruction.39 if-nez vx,target Checks vx and jumps if vx is nonzero2. 3902 1200 - if-nez v2, 0014 // +0012
Jumps to current position+18 words (hex 12) if v2 is nonzero. 0014 is the label of the target instruction.3A if-ltz vx,target Checks vx and jumps if vx<02. 3A00 1600 - if-ltz v0, 002d // +0016
Jumps to the current position+16H words if v0<0. 002d is the label of the target instruction.3B if-gez vx,target Checks vx and jumps if vx>=02. 3B00 1600 - if-gez v0, 002d // +0016
Jumps to the current position+16H words if v0 >=0. 002d is the label of the target instruction.3C if-gtz vx,target Checks vx and jumps if vx>02. 3C00 1D00 - if-gtz v0, 004a // +001d
Jumps to the current position+1DH words if v0>0. 004A is the label of the target instruction.3D if-lez vx,target Checks vx and jumps if vx<=02. 3D00 1D00 - if-lez v0, 004a // +001d
Jumps to the current position+1DH words if v0<=0. 004A is the label of the target instruction.3E unused_3E 3F unused_3F 40 unused_40 41 unused_41 42 unused_42 43 unused_43 44 aget vx,vy,vz Gets an integer value of an object reference array into vx. The array is referenced by vy and is indexed by vz. 4407 0306 - aget v7, v3, v6
Gets an integer array element. The array is referenced by v3 and the element is indexed by v6. The element will be put into v7.45 aget-wide vx,vy,vz Gets a long/double value of long/double array into vx,vx+1. The array is referenced by vy and is indexed by vz. 4505 0104 - aget-wide v5, v1, v4
Gets a long/double array element. The array is referenced by v1 and the element is indexed by v4. The element will be put into v5,v6.46 aget-object vx,vy,vz Gets an object reference value of an object reference array into vx. The array is referenced by vy and is indexed by vz. 4602 0200 - aget-object v2, v2, v0
Gets an object reference array element. The array is referenced by v2 and the element is indexed by v0. The element will be put into v2.47 aget-boolean vx,vy,vz Gets a boolean value of a boolean array into vx. The array is referenced by vy and is indexed by vz. 4700 0001 - aget-boolean v0, v0, v1
Gets a boolean array element. The array is referenced by v0 and the element is indexed by v1. The element will be put into v0.48 aget-byte vx,vy,vz Gets a byte value of a byte array into vx. The array is referenced by vy and is indexed by vz. 4800 0001 - aget-byte v0, v0, v1
Gets a byte array element. The array is referenced by v0 and the element is indexed by v1. The element will be put into v0.49 aget-char vx, vy,vz Gets a char value of a character array into vx. The element is indexed by vz, the array object is referenced by vy 4905 0003 - aget-char v5, v0, v3
Gets a character array element. The array is referenced by v0 and the element is indexed by v3. The element will be put into v5.4A aget-short vx,vy,vz Gets a short value of a short array into vx. The element is indexed by vz, the array object is referenced by vy. 4A00 0001 - aget-short v0, v0, v1
Gets a short array element. The array is referenced by v0 and the element is indexed by v1. The element will be put into v0.4B aput vx,vy,vz Puts the integer value in vx into an element of an integer array. The element is indexed by vz, the array object is referenced by vy. 4B00 0305 - aput v0, v3, v5
Puts the integer value in v2 into an integer array referenced by v0. The target array element is indexed by v1.4C aput-wide vx,vy,vz Puts the double/long value in vx,vx+1 into a double/long array. The array is referenced by vy, the element is indexed by vz. 4C05 0104 - aput-wide v5, v1, v4
Puts the double/long value in v5,v6 into a double/long array referenced by v1. The target array element is indexed by v4.4D aput-object vx,vy,vz Puts the object reference value in vx into an element of an object reference array. The element is indexed by vz, the array object is referenced by vy. 4D02 0100 - aput-object v2, v1, v0
Puts the object reference value in v2 into an object reference array referenced by v0. The target array element is indexed by v1.4E aput-boolean vx,vy,vz Puts the boolean value in vx into an element of a boolean array. The element is indexed by vz, the array object is referenced by vy. 4E01 0002 - aput-boolean v1, v0, v2
Puts the boolean value in v1 into an object reference array referenced by v0. The target array element is indexed by v2.4F aput-byte vx,vy,vz Puts the byte value in vx into an element of a byte array. The element is indexed by vz, the array object is referenced by vy. 4F02 0001 - aput-byte v2, v0, v1
Puts the boolean value in v2 into a byte array referenced by v0. The target array element is indexed by v1.50 aput-char vx,vy,vz Puts the char value in vx into an element of a character array. The element is indexed by vz, the array object is referenced by vy. 5003 0001 - aput-char v3, v0, v1
Puts the character value in v3 into a character array referenced by v0. The target array element is indexed by v1.51 aput-short vx,vy,vz Puts the short value in vx into an element of a short array. The element is indexed by vz, the array object is referenced by vy. 5102 0001 - aput-short v2, v0, v1
Puts the short value in v2 into a character array referenced by v0. The target array element is indexed by v1.52 iget vx, vy, field_id Reads an instance field into vx. The instance is referenced by vy. 5210 0300 - iget v0, v1, Test2.i6:I // field@0003
Reads field@0003 into v0 (entry #3 in the field id table). The instance is referenced by v1.53 iget-wide vx,vy,field_id Reads an instance field into vx1. The instance is referenced by vy. 5320 0400 - iget-wide v0, v2, Test2.l0:J // field@0004
Reads field@0004 into v0 and v1 registers (entry #4 in the field id table). The instance is referenced by v2.54 iget-object vx,vy,field_id Reads an object reference instance field into vx. The instance is referenced by vy. iget-object v1, v2, LineReader.fis:Ljava/io/FileInputStream; // field@0002
Reads field@0002 into v1 (entry #2 in the field id table). The instance is referenced by v2.55 iget-boolean vx,vy,field_id Reads a boolean instance field into vx. The instance is referenced by vy. 55FC 0000 - iget-boolean v12, v15, Test2.b0:Z // field@0000
Reads the boolean field@0000 into v12 register (entry #0 in the field id table). The instance is referenced by v15.56 iget-byte vx,vy,field_id Reads a byte instance field into vx. The instance is referenced by vy. 5632 0100 - iget-byte v2, v3, Test3.bi1:B // field@0001
Reads the char field@0001 into v2 register (entry #1 in the field id table). The instance is referenced by v3.57 iget-char vx,vy,field_id Reads a char instance field into vx. The instance is referenced by vy. 5720 0300 - iget-char v0, v2, Test3.ci1:C // field@0003
Reads the char field@0003 into v0 register (entry #3 in the field id table). The instance is referenced by v2.58 iget-short vx,vy,field_id Reads a short instance field into vx. The instance is referenced by vy. 5830 0800 - iget-short v0, v3, Test3.si1:S // field@0008
Reads the short field@0008 into v0 register (entry #8 in the field id table). The instance is referenced by v3.59 iput vx,vy, field_id Puts vx into an instance field. The instance is referenced by vy. 5920 0200 - iput v0,v2, Test2.i6:I // field@0002
Stores v0 into field@0002 (entry #2 in the field id table). The instance is referenced by v2.5A iput-wide vx,vy, field_id Puts the wide value located in vx and vx+1 registers into an instance field. The instance is referenced by vy. 5A20 0000 - iput-wide v0,v2, Test2.d0:D // field@0000
Stores the wide value in v0, v1 registers into field@0000 (entry #0 in the field id table). The instance is referenced by v2.5B iput-object vx,vy,field_id Puts the object reference in vx into an instance field. The instance is referenced by vy. 5B20 0000 - iput-object v0, v2, LineReader.bis:Ljava/io/BufferedInputStream; // field@0000
Stores the object reference in v0 into field@0000 (entry #0 in the field table). The instance is referenced by v2.5C iput-boolean vx,vy, field_id Puts the boolean value located in vx into an instance field. The instance is referenced by vy. 5C30 0000 - iput-boolean v0, v3, Test2.b0:Z // field@0000
Puts the boolean value in v0 into field@0000 (entry #0 in the field id table). The instance is referenced by v3.5D iput-byte vx,vy,field_id Puts the byte value located in vx into an instance field. The instance is referenced by vy. 5D20 0100 - iput-byte v0, v2, Test3.bi1:B // field@0001
Puts the boolean value in v0 into field@0001 (entry #1 in the field id table). The instance is referenced by v2.5E iput-char vx,vy,field_id Puts the char value located in vx into an instance field. The instance is referenced by vy. 5E20 0300 - iput-char v0, v2, Test3.ci1:C // field@0003
Puts the char value in v0 into field@0003 (entry #3 in the field id table). The instance is referenced by v2.5F iput-short vx,vy,field_id Puts the short value located in vx into an instance field. The instance is referenced by vy. 5F21 0800 - iput-short v1, v2, Test3.si1:S // field@0008
Puts the short value in v1 into field@0008 (entry #8 in the field id table). The instance is referenced by v2.60 sget vx,field_id Reads the integer field identified by the field_id into vx. 6000 0700 - sget v0, Test3.is1:I // field@0007
Reads field@0007 (entry #7 in the field id table) into v0.61 sget-wide vx, field_id Reads the static field identified by the field_id into vx and vx+1 registers. 6100 0500 - sget-wide v0, Test2.l1:J // field@0005
Reads field@0005 (entry #5 in the field id table) into v0 and v1 registers.62 sget-object vx,field_id Reads the object reference field identified by the field_id into vx. 6201 0C00 - sget-object v1, Test3.os1:Ljava/lang/Object; // field@000c
Reads field@000c (entry #CH in the field id table) into v1.63 sget-boolean vx,field_id Reads the boolean static field identified by the field_id into vx. 6300 0C00 - sget-boolean v0, Test2.sb:Z // field@000c
Reads boolean field@000c (entry #12 in the field id table) into v0.64 sget-byte vx,field_id Reads the byte static field identified by the field_id into vx. 6400 0200 - sget-byte v0, Test3.bs1:B // field@0002
Reads byte field@0002 (entry #2 in the field id table) into v0.65 sget-char vx,field_id Reads the char static field identified by the field_id into vx. 6500 0700 - sget-char v0, Test3.cs1:C // field@0007
Reads byte field@0007 (entry #7 in the field id table) into v0.66 sget-short vx,field_id Reads the short static field identified by the field_id into vx. 6600 0B00 - sget-short v0, Test3.ss1:S // field@000b
Reads short field@000b (entry #BH in the field id table) into v0.67 sput vx, field_id Puts vx into a static field. 6700 0100 - sput v0, Test2.i5:I // field@0001
Stores v0 into field@0001 (entry #1 in the field id table).68 sput-wide vx, field_id Puts vx and vx+1 into a static field. 6800 0500 - sput-wide v0, Test2.l1:J // field@0005
Puts the long value in v0 and v1 into the field@0005 static field (entry #5 in the field id table).69 sput-object vx,field_id Puts object reference in vx into a static field. 6900 0c00 - sput-object v0, Test3.os1:Ljava/lang/Object; // field@000c
Puts the object reference value in v0 into the field@000c static field (entry #CH in the field id table).6A sput-boolean vx,field_id Puts boolean value in vx into a static field. 6A00 0300 - sput-boolean v0, Test3.bls1:Z // field@0003
Puts the byte value in v0 into the field@0003 static field (entry #3 in the field id table).6B sput-byte vx,field_id Puts byte value in vx into a static field. 6B00 0200 - sput-byte v0, Test3.bs1:B // field@0002
Puts the byte value in v0 into the field@0002 static field (entry #2 in the field id table).6C sput-char vx,field_id Puts char value in vx into a static field. 6C01 0700 - sput-char v1, Test3.cs1:C // field@0007
Puts the char value in v1 into the field@0007 static field (entry #7 in the field id table).6D sput-short vx,field_id Puts short value in vx into a static field. 6D00 0B00 - sput-short v0, Test3.ss1:S // field@000b
Puts the short value in v0 into the field@000b static field (entry #BH in the field id table).6E invoke-virtual { parameters }, methodtocall Invokes a virtual method with parameters. 6E53 0600 0421 - invoke-virtual { v4, v0, v1, v2, v3}, Test2.method5:(IIII)V // method@0006
Invokes the 6th method in the method table with the following arguments: v4 is the "this" instance, v0, v1, v2, and v3 are the method parameters. The method has 5 arguments (4 MSB bits of the second byte)5.6F invoke-super {parameter},methodtocall Invokes the virtual method of the immediate parent class. 6F10 A601 0100 invoke-super {v1},java.io.FilterOutputStream.close:()V // method@01a6
Invokes method@01a6 with one parameter, v1.70 invoke-direct { parameters }, methodtocall Invokes a method with parameters without the virtual method resolution. 7010 0800 0100 - invoke-direct {v1}, java.lang.Object.<init>:()V // method@0008
Invokes the 8th method in the method table with just one parameter, v1 is the "this" instance5.71 invoke-static {parameters}, methodtocall Invokes a static method with parameters. 7110 3400 0400 - invoke-static {v4}, java.lang.Integer.parseInt:( Ljava/lang/String;)I // method@0034
Invokes method@34 static method. The method is called with one parameter, v45.72 invoke-interface {parameters},methodtocall Invokes an interface method. 7240 2102 3154 invoke-interface {v1, v3, v4, v5}, mwfw.IReceivingProtocolAdapter.receivePackage:(
ILjava/lang/String;Ljava/io/InputStream;)Z // method@0221
Invokes method@221 interface method using parameters in v1,v3,v4 and v55.73 unused_73 74 invoke-virtual/range {vx..vy},methodtocall Invokes virtual method with a range of registers. The instruction specifies the first register and the number of registers to be passed to the method. 7403 0600 1300 - invoke-virtual {v19..v21}, Test2.method5:(IIII)V // method@0006
Invokes the 6th method in the method table with the following arguments: v19 is the "this" instance, v20 and v21 are the method parameters.75 invoke-super/range Invokes the virtual method of the immediate parent class. The instruction specifies the first register and the number of registers to be passed to the method. 7501 A601 0100 invoke-super {v1},java.io.FilterOutputStream.close:()V // method@01a6
Invokes method@01a6 with one parameter, v1.76 invoke-direct/range {vx..vy},methodtocall Invokes direct method with a range of registers. The instruction specifies the first register and the number of registers to be passed to the method. 7603 3A00 1300 - invoke-direct/range {v19..21},java.lang.Object.<init>:()V // method@003a
Invokes method@3A with 1 parameters (second byte of the instruction=03). The parameter is stored in v19 (5th,6th bytes of the instruction).77 invoke-static/range {vx..vy},methodtocall Invokes static method with a range of registers. The instruction specifies the first register and the number of registers to be passed to the method. 7703 3A00 1300 - invoke-static/range {v19..21},java.lang.Integer.parseInt:( Ljava/lang/String;)I // method@0034
Invokes method@3A with 1 parameters (second byte of the instruction=03). The parameter is stored in v19 (5th,6th bytes of the instruction).78 invoke-interface-range Invokes an interface method with a range of registers. The instruction specifies the first register and the number of registers to be passed to the method. 7840 2102 0100 invoke-interface {v1..v4}, mwfw.IReceivingProtocolAdapter.receivePackage:(
ILjava/lang/String;Ljava/io/InputStream;)Z // method@0221
Invokes method@221 interface method using parameters in v1..v4.79 unused_79 7A unused_7A 7B neg-int vx,vy Calculates vx=-vy. 7B01 - neg-int v1,v0
Calculates -v0 and stores the result in v1.7C not-int vx,vy 7D neg-long vx,vy Calculates vx,vx+1=-(vy,vy+1) 7D02 - neg-long v2,v0
Calculates -(v0,v1) and stores the result into (v2,v3)7E not-long vx,vy 7F neg-float vx,vy Calculates vx=-vy 7F01 - neg-float v1,v0
Calculates -v0 and stores the result into v1.80 neg-double vx,vy Calculates vx,vx+1=-(vy,vy+1) 8002 - neg-double v2,v0
Calculates -(v0,v1) and stores the result into (v2,v3)81 int-to-long vx, vy Converts the integer in vy into a long in vx,vx+1. 8106 - int-to-long v6, v0
Converts an integer in v0 into a long in v6,v7.82 int-to-float vx, vy Converts the integer in vx into a float in vx. 8206 - int-to-float v6, v0
Converts the integer in v0 into a float in v6.83 int-to-double vx, vy Converts the integer in vy into the double in vx,vx+1. 8306 - int-to-double v6, v0
Converts the integer in v0 into a double in v6,v784 long-to-int vx,vy Converts the long value in vy,vy+1 into an integer in vx. 8424 - long-to-int v4, v2
Converts the long value in v2,v3 into an integer value in v4.85 long-to-float vx, vy Converts the long value in vy,vy+1 into a float in vx. 8510 - long-to-float v0, v1
Convcerts the long value in v1,v2 into a float value in v0.86 long-to-double vx, vy Converts the long value in vy,vy+1 into a double value in vx,vx+1. 8610 - long-to-double v0, v1
Converts the long value in v1,v2 into a double value in v0,v1.87 float-to-int vx, vy Converts the float value in vy into an integer value in vx. 8730 - float-to-int v0, v3
Converts the float value in v3 into an integer value in v0.88 float-to-long vx,vy Converts the float value in vy into a long value in vx. 8830 - float-to-long v0, v3
Converts the float value in v3 into a long value in v0,v1.89 float-to-double vx, vy Converts the float value in vy into a double value in vx,vx+1. 8930 - float-to-double v0, v3
Converts the float value in v3 into a double value in v0,v1.8A double-to-int vx, vy Converts the double value in vy,vy+1 into an integer value in vx. 8A40 - double-to-int v0, v4
Converts the double value in v4,v5 into an integer value in v0.8B double-to-long vx, vy Converts the double value in vy,vy+1 into a long value in vx,vx+1. 8B40 - double-to-long v0, v4
Converts the double value in v4,v5 into a long value in v0,v1.8C double-to-float vx, vy Converts the double value in vy,vy+1 into a float value in vx. 8C40 - double-to-float v0, v4
Converts the double value in v4,v5 into a float value in v0,v1.8D int-to-byte vx,vy Converts the int value in vy to a byte value and stores it in vx. 8D00 - int-to-byte v0, v0
Converts the integer in v0 into a byte and puts the byte value into v0.8E int-to-char vx,vy Converts the int value in vy to a char value and stores it in vx. 8E33 - int-to-char v3, v3
Converts the integer in v3 into a char and puts the char value into v3.8F int-to-short vx,vy Converts the int value in vy to a short value and stores it in vx. 8F00 - int-to-short v0, v0
Converts the integer in v0 into a short and puts the short value into v3.90 add-int vx,vy,vz Calculates vy+vz and puts the result into vx. 9000 0203 - add-int v0, v2, v3
Adds v3 to v2 and puts the result into v04.91 sub-int vx,vy,vz Calculates vy-vz and puts the result into vx. 9100 0203 - sub-int v0, v2, v3
Subtracts v3 from v2 and puts the result into v0.92 mul-int vx, vy, vz Multiplies vz with wy and puts the result int vx. 9200 0203 - mul-int v0,v2,v3
Multiplies v2 with w3 and puts the result into v093 div-int vx,vy,vz Divides vy with vz and puts the result into vx. 9303 0001 - div-int v3, v0, v1
Divides v0 with v1 and puts the result into v3.94 rem-int vx,vy,vz Calculates vy % vz and puts the result into vx. 9400 0203 - rem-int v0, v2, v3
Calculates v3 % v2 and puts the result into v0.95 and-int vx, vy, vz Calculates vy AND vz and puts the result into vx. 9503 0001 - and-int v3, v0, v1
Calculates v0 AND v1 and puts the result into v3.96 or-int vx, vy, vz Calculates vy OR vz and puts the result into vx. 9603 0001 - or-int v3, v0, v1
Calculates v0 OR v1 and puts the result into v3.97 xor-int vx, vy, vz Calculates vy XOR vz and puts the result into vx. 9703 0001 - xor-int v3, v0, v1
Calculates v0 XOR v1 and puts the result into v3.98 shl-int vx, vy, vz Shift vy left by the positions specified by vz and store the result into vx. 9802 0001 - shl-int v2, v0, v1
Shift v0 left by the positions specified by v1 and store the result in v2.99 shr-int vx, vy, vz Shift vy right by the positions specified by vz and store the result into vx. 9902 0001 - shr-int v2, v0, v1
Shift v0 right by the positions specified by v1 and store the result in v2.9A ushr-int vx, vy, vz Unsigned shift right (>>>) vy by the positions specified by vz and store the result into vx. 9A02 0001 - ushr-int v2, v0, v1
Unsigned shift v0 right by the positions specified by v1 and store the result in v2.9B add-long vx, vy, vz Adds vy to vz and puts the result into vx1. 9B00 0305 - add-long v0, v3, v5
The long value in v3,v4 is added to the value in v5,v6 and the result is stored in v0,v1.9C sub-long vx,vy,vz Calculates vy-vz and puts the result into vx1. 9C00 0305 - sub-long v0, v3, v5
Subtracts the long value in v5,v6 from the long value in v3,v4 and puts the result into v0,v1.9D mul-long vx,vy,vz Calculates vy*vz and puts the result into vx1. 9D00 0305 - mul-long v0, v3, v5
Multiplies the long value in v5,v6 with the long value in v3,v4 and puts the result into v0,v1.9E div-long vx, vy, vz Calculates vy/vz and puts the result into vx1. 9E06 0002 - div-long v6, v0, v2
Divides the long value in v0,v1 with the long value in v2,v3 and pust the result into v6,v7.9F rem-long vx,vy,vz Calculates vy % vz and puts the result into vx1. 9F06 0002 - rem-long v6, v0, v2
Calculates v0,v1 % v2,v3 and puts the result into v6,v7.A0 and-long vx, vy, vz Calculates the vy AND vz and puts the result into vx1. A006 0002 - and-long v6, v0, v2
Calculates v0,v1 AND v2,v3 and puts the result into v6,v7.A1 or-long vx, vy, vz Calculates the vy OR vz and puts the result into vx1. A106 0002 - or-long v6, v0, v2
Calculates v0,v1 OR v2,v3 and puts the result into v6,v7.A2 xor-long vx, vy, vz Calculates the vy XOR vz and puts the result into vx1. A206 0002 - xor-long v6, v0, v2
Calculates v0,v1 XOR v2,v3 and puts the result into v6,v7.A3 shl-long vx, vy, vz Shifts left vy by vz positions and stores the result in vx1. A302 0004 - shl-long v2, v0, v4
Shift v0,v1 by postions specified by v4 and puts the result into v2,v3.A4 shr-long vx,vy,vz Shifts right vy by vz positions and stores the result in vx1. A402 0004 - shr-long v2, v0, v4
Shift v0,v1 by postions specified by v4 and puts the result into v2,v3.A5 ushr-long vx, vy, vz Unsigned shifts right vy by vz positions and stores the result in vx1. A502 0004 - ushr-long v2, v0, v4
Unsigned shift v0,v1 by postions specified by v4 and puts the result into v2,v3.A6 add-float vx,vy,vz Adds vy to vz and puts the result into vx. A600 0203 - add-float v0, v2, v3
Adds the floating point numbers in v2 and v3 and puts the result into v0.A7 sub-float vx,vy,vz Calculates vy-vz and puts the result into vx. A700 0203 - sub-float v0, v2, v3
Calculates v2-v3 and puts the result into v0.A8 mul-float vx, vy, vz Multiplies vy with vz and puts the result into vx. A803 0001 - mul-float v3, v0, v1
Multiplies v0 with v1 and puts the result into v3.A9 div-float vx, vy, vz Calculates vy/vz and puts the result into vx. A903 0001 - div-float v3, v0, v1
Divides v0 with v1 and puts the result into v3.AA rem-float vx,vy,vz Calculates vy % vz and puts the result into vx. AA03 0001 - rem-float v3, v0, v1
Calculates v0 % v1 and puts the result into v3.AB add-double vx,vy,vz Adds vy to vz and puts the result into vx1. AB00 0305 - add-double v0, v3, v5
Adds the double value in v5,v6 registers to the double value in v3,v4 registers and places the result in v0,v1 registers.AC sub-double vx,vy,vz Calculates vy-vz and puts the result into vx1. AC00 0305 - sub-double v0, v3, v5
Subtracts the value in v5,v6 from the value in v3,v4 and puts the result into v0,v1.AD mul-double vx, vy, vz Multiplies vy with vz and puts the result into vx1. AD06 0002 - mul-double v6, v0, v2
Multiplies the double value in v0,v1 with the double value in v2,v3 and puts the result into v6,v7.AE div-double vx, vy, vz Calculates vy/vz and puts the result into vx1. AE06 0002 - div-double v6, v0, v2
Divides the double value in v0,v1 with the double value in v2,v3 and puts the result into v6,v7.AF rem-double vx,vy,vz Calculates vy % vz and puts the result into vx1. AF06 0002 - rem-double v6, v0, v2
Calculates v0,v1 % v2,v3 and puts the result into v6,v7.B0 add-int/2addr vx,vy Adds vy to vx. B010 - add-int/2addr v0,v1
Adds v1 to v0.B1 sub-int/2addr vx,vy Calculates vx-vy and puts the result into vx. B140 - sub-int/2addr v0, v4
Subtracts v4 from v0 and puts the result into v0.B2 mul-int/2addr vx,vy Multiplies vx with vy. B210 - mul-int/2addr v0, v1
Multiples v0 with v1 and puts the result into v0.B3 div-int/2addr vx,vy Divides vx with vy and puts the result into vx. B310 - div-int/2addr v0, v1
Divides v0 with v1 and puts the result into v0.B4 rem-int/2addr vx,vy Calculates vx % vy and puts the result into vx B410 - rem-int/2addr v0, v1
Calculates v0 % v1 and puts the result into v0.B5 and-int/2addr vx, vy Calculates vx AND vy and puts the result into vx. B510 - and-int/2addr v0, v1
Calculates v0 AND v1 and puts the result into v0.B6 or-int/2addr vx, vy Calculates vx OR vy and puts the result into vx. B610 - or-int/2addr v0, v1
Calculates v0 OR v1 and puts the result into v0.B7 xor-int/2addr vx, vy Calculates vx XOR vy and puts the result into vx. B710 - xor-int/2addr v0, v1
Calculates v0 XOR v1 and puts the result into v0.B8 shl-int/2addr vx, vy Shifts vx left by vy positions. B810 - shl-int/2addr v0, v1
Shift v0 left by v1 positions.B9 shr-int/2addr vx, vy Shifts vx right by vy positions. B910 - shr-int/2addr v0, v1
Shift v0 right by v1 positions.BA ushr-int/2addr vx, vy Unsigned shift right (>>>) vx by the positions specified by vy. BA10 - ushr-int/2addr v0, v1
Unsigned shift v0 by the positions specified by v1.BB add-long/2addr vx,vy Adds vy to vx1. BB20 - add-long/2addr v0, v2
Adds the long value in v2,v3 registers to the long value in v0,v1 registers.BC sub-long/2addr vx,vy Calculates vx-vy and puts the result into vx1. BC70 - sub-long/2addr v0, v7
Subtracts the long value in v7,v8 from the long value in v0,v1 and puts the result into v0,v1.BD mul-long/2addr vx,vy Calculates vx*vy and puts the result into vx1. BD70 - mul-long/2addr v0, v7
Multiplies the long value in v7,v8 with the long value in v0,v1 and puts the result into v0,v1.BE div-long/2addr vx, vy Calculates vx/vy and puts the result into vx1. BE20 - div-long/2addr v0, v2
Divides the long value in v0,v1 with the long value in v2,v3 and puts the result into v0,v1BF rem-long/2addr vx,vy Calculates vx % vy and puts the result into vx1. BF20 - rem-long/2addr v0, v2
Calculates v0,v1 % v2,v3 and puts the result into v0,v1C0 and-long/2addr vx, vy Calculates vx AND vy and puts the result into vx1. C020 - and-long/2addr v0, v2
Calculates v0,v1 OR v2,v3 and puts the result into v0,v1.C1 or-long/2addr vx, vy Calculates vx OR vy and puts the result into vx1. C120 - or-long/2addr v0, v2
Calculates v0,v1 OR v2,v3 and puts the result into v0,v1.C2 xor-long/2addr vx, vy Calculates vx XOR vy and puts the result into vx1. C220 - xor-long/2addr v0, v2
Calculates v0,v1 XOR v2,v3 and puts the result into v0,v1.C3 shl-long/2addr vx, vy Shifts left the value in vx,vx+1 by the positions specified by vy and stores the result in vx,vx+1. C320 - shl-long/2addr v0, v2
Shifts left v0,v1 by the positions specified by v2.C4 shr-long/2addr vx, vy Shifts right the value in vx,vx+1 by the positions specified by vy and stores the result in vx,vx+1. C420 - shr-long/2addr v0, v2
Shifts right v0,v1 by the positions specified by v2.C5 ushr-long/2addr vx, vy Unsigned shifts right the value in vx,vx+1 by the positions specified by vy and stores the result in vx,vx+1. C520 - ushr-long/2addr v0, v2
Unsigned shifts right v0,v1 by the positions specified by v2.C6 add-float/2addr vx,vy Adds vy to vx. C640 - add-float/2addr v0,v4
Adds v4 to v0.C7 sub-float/2addr vx,vy Calculates vx-vy and stores the result in vx. C740 - sub-float/2addr v0,v4
Adds v4 to v0.C8 mul-float/2addr vx, vy Multiplies vx with vy. C810 - mul-float/2addr v0, v1
Multiplies v0 with v1.C9 div-float/2addr vx, vy Calculates vx/vy and puts the result into vx. C910 - div-float/2addr v0, v1
Divides v0 with v1 and puts the result into v0.CA rem-float/2addr vx,vy Calculates vx/vy and puts the result into vx. CA10 - rem-float/2addr v0, v1
Calculates v0 % v1 and puts the result into v0.CB add-double/2addr vx, vy Adds vy to vx1. CB70 - add-double/2addr v0, v7
Adds v7 to v0.CC sub-double/2addr vx, vy Calculates vx-vy and puts the result into vx1. CC70 - sub-double/2addr v0, v7
Subtracts the value in v7,v8 from the value in v0,v1 and puts the result into v0,v1.CD mul-double/2addr vx, vy Multiplies vx with vy1. CD20 - mul-double/2addr v0, v2
Multiplies the double value in v0,v1 with the double value in v2,v3 and puts the result into v0,v1.CE div-double/2addr vx, vy Calculates vx/vy and puts the result into vx1. CE20 - div-double/2addr v0, v2
Divides the double value in v0,v1 with the double value in v2,v3 and puts the value into v0,v1.CF rem-double/2addr vx,vy Calculates vx % vy and puts the result into vx1. CF20 - rem-double/2addr v0, v2
Calculates v0,v1 % v2,v3 and puts the value into v0,v1.D0 add-int/lit16 vx,vy,lit16 Adds vy to lit16 and stores the result into vx. D001 D204 - add-int/lit16 v1, v0, #int 1234 // #04d2
Adds v0 to literal 1234 and stores the result into v1.D1 sub-int/lit16 vx,vy,lit16 Calculates vy - lit16 and stores the result into vx. D101 D204 - sub-int/lit16 v1, v0, #int 1234 // #04d2
Calculates v0 - literal 1234 and stores the result into v1.D2 mul-int/lit16 vx,vy,lit16 Calculates vy * lit16 and stores the result into vx. D201 D204 - mul-int/lit16 v1, v0, #int 1234 // #04d2
Calculates v0 * literal 1234 and stores the result into v1.D3 div-int/lit16 vx,vy,lit16 Calculates vy / lit16 and stores the result into vx. D301 D204 - div-int/lit16 v1, v0, #int 1234 // #04d2
Calculates v0 / literal 1234 and stores the result into v1.D4 rem-int/lit16 vx,vy,lit16 Calculates vy % lit16 and stores the result into vx. D401 D204 - rem-int/lit16 v1, v0, #int 1234 // #04d2
Calculates v0 % literal 1234 and stores the result into v1.D5 and-int/lit16 vx,vy,lit16 Calculates vy AND lit16 and stores the result into vx. D501 D204 - and-int/lit16 v1, v0, #int 1234 // #04d2
Calculates v0 AND literal 1234 and stores the result into v1.D6 or-int/lit16 vx,vy,lit16 Calculates vy OR lit16 and stores the result into vx. D601 D204 - or-int/lit16 v1, v0, #int 1234 // #04d2
Calculates v0 OR literal 1234 and stores the result into v1.D7 xor-int/lit16 vx,vy,lit16 Calculates vy XOR lit16 and stores the result into vx. D701 D204 - xor-int/lit16 v1, v0, #int 1234 // #04d2
Calculates v0 XOR literal 1234 and stores the result into v1.D8 add-int/lit8 vx,vy,lit8 Adds vy to lit8 and stores the result into vx. D800 0201 - add-int/lit8 v0,v2, #int1
Adds literal 1 to v2 and stores the result into v0.D9 sub-int/lit8 vx,vy,lit8 Calculates vy-lit8 and stores the result into vx. D900 0201 - sub-int/lit8 v0,v2, #int1
Calculates v2-1 and stores the result into v0.DA mul-int/lit-8 vx,vy,lit8 Multiplies vy with lit8 8-bit literal constant and puts the result into vx. DA00 0002 - mul-int/lit8 v0,v0, #int2
Multiplies v0 with literal 2 and puts the result into v0.DB div-int/lit8 vx,vy,lit8 Calculates vy/lit8 and stores the result into vx. DB00 0203 - mul-int/lit8 v0,v2, #int3
Calculates v2/3 and stores the result into v0.DC rem-int/lit8 vx,vy,lit8 Calculates vy % lit8 and stores the result into vx. DC00 0203 - rem-int/lit8 v0,v2, #int3
Calculates v2 % 3 and stores the result into v0.DD and-int/lit8 vx,vy,lit8 Calculates vy AND lit8 and stores the result into vx. DD00 0203 - and-int/lit8 v0,v2, #int3
Calculates v2 AND 3 and stores the result into v0.DE or-int/lit8 vx, vy, lit8 Calculates vy OR lit8 and puts the result into vx. DE00 0203 - or-int/lit8 v0, v2, #int 3
Calculates v2 OR literal 3 and puts the result into v0.DF xor-int/lit8 vx, vy, lit8 Calculates vy XOR lit8 and puts the result into vx. DF00 0203 | 0008: xor-int/lit8 v0, v2, #int 3
Calculates v2 XOR literal 3 and puts the result into v0.E0 shl-int/lit8 vx, vy, lit8 Shift v0 left by the bit positions specified by the literal constant and put the result into vx. E001 0001 - shl-int/lit8 v1, v0, #int 1
Shift v0 left by 1 position and put the result into v1.E1 shr-int/lit8 vx, vy, lit8 Shift v0 right by the bit positions specified by the literal constant and put the result into vx. E101 0001 - shr-int/lit8 v1, v0, #int 1
Shift v0 right by 1 position and put the result into v1.E2 ushr-int/lit8 vx, vy, lit8 Unsigned right shift of v0 (>>>) by the bit positions specified by the literal constant and put the result into vx. E201 0001 - ushr-int/lit8 v1, v0, #int 1
Unsigned shift v0 right by 1 position and put the result into v1.E3 unused_E3 E4 unused_E4 E5 unused_E5 E6 unused_E6 E7 unused_E7 E8 unused_E8 E9 unused_E9 EA unused_EA EB unused_EB EC unused_EC ED unused_ED EE execute-inline {parameters},inline ID Executes the inline method identified by inline ID6. EE20 0300 0100 - execute-inline {v1, v0}, inline #0003
Executes inline method #3 using v1 as "this" and passing one parameter in v0.EF unused_EF F0 invoke-direct-empty Stands as a placeholder for pruned empty methods like Object.<init>. This acts as nop during normal execution6. F010 F608 0000 - invoke-direct-empty {v0}, Ljava/lang/Object;.<init>:()V // method@08f6
Replacement for the empty method java/lang/Object;<init>.F1 unused_F1 F2 iget-quick vx,vy,offset Gets the value stored at offset in vy instance's data area to vx6. F221 1000 - iget-quick v1, v2, [obj+0010]
Gets the value at offset 0CH of the instance pointed by v2 and stores the object reference in v1.F3 iget-wide-quick vx,vy,offset Gets the object reference value stored at offset in vy instance's data area to vx,vx+16. F364 3001 - iget-wide-quick v4, v6, [obj+0130]
Gets the value at offset 130H of the instance pointed by v6 and stores the object reference in v4,v5.F4 iget-object-quick vx,vy,offset Gets the object reference value stored at offset in vy instance's data area to vx6. F431 0C00 - iget-object-quick v1, v3, [obj+000c]
Gets the object reference value at offset 0CH of the instance pointed by v3 and stores the object reference in v1.F5 iput-quick vx,vy,offset Puts the value stored in vx to offset in vy instance's data area6. F521 1000 - iput-quick v1, v2, [obj+0010]
Puts the object reference value in v1 to offset 10H of the instance pointed by v2.F6 iput-wide-quick vx,vy,offset Puts the value stored in vx,vx+1 to offset in vy instance's data area6. F652 7001 - iput-wide-quick v2, v5, [obj+0170]
Puts the value in v2,v3 to offset 170H of the instance pointed by v5.F7 iput-object-quick vx,vy,offset Puts the object reference value stored in vx to offset in vy instance's data area to vx6. F701 4C00 - iput-object-quick v1, v0, [obj+004c]
Puts the object reference value in v1 to offset 0CH of the instance pointed by v3.F8 invoke-virtual-quick {parameters},vtable offset Invokes a virtual method using the vtable of the target object6. F820 B800 CF00 - invoke-virtual-quick {v15, v12}, vtable #00b8
Invokes a virtual method. The target object instance is pointed by v15 and vtable entry #B8 points to the method to be called. v12 is a parameter to the method call.F9 invoke-virtual-quick/range {parameter range},vtable offset Invokes a virtual method using the vtable of the target object6 F906 1800 0000 - invoke-virtual-quick/range {v0..v5},vtable #0018
Invokes a method using the vtable of the instance pointed by v0. v1..v5 registers are parameters to the method call.FA invoke-super-quick {parameters},vtable offset Invokes a virtual method in the target object's immediate parent class using the vtable of that parent class6. FA40 8100 3254 - invoke-super-quick {v2, v3, v4, v5}, vtable #0081
Invokes a method using the vtable of the immediate parent class of instance pointed by v2. v3, v4 and v5 registers are parameters to the method call.FB invoke-super-quick/range {register range},vtable offset Invokes a virtual method in the target object's immediate parent class using the vtable of that parent class6. F906 1B00 0000 - invoke-super-quick/range {v0..v5}, vtable #001b
Invokes a method using the vtable of the immediate parent class of instance pointed by v0. v1..v5 registers are parameters to the method call.FC unused_FC FD unused_FD FE unused_FE FF unused_FF
詳解smali文件:
- 上面我們介紹了Dalvik的相關指令,下面我們則來認識一下smali文件.盡管我們使用java來寫Android應用,但是Dalvik並不直接加載.class文件,而是通過dx工具將.class文件優化成.dex文件,然后交由Dalvik加載.這樣說來,我們無法通過分析.class來直接分析apk文件,而是需要借助工具baksmali.jar反編譯dex文件來獲得對應smali文件,smali文件可以認為是Davilk的字節碼文件,但是並兩者並不完全等同.
- 通過baksmali.jar反編譯出來每個.smali,都對應與java中的一個類,每個smali文件都是Davilk指令組成的,並遵循一定的結構.smali存在很多的指令用於描述對應的java文件,所有的指令都以”.”開頭,常用的指令如下:
關鍵詞 說明 .filed 定義字段 .method…end method 定義方法 .annotation…end annotation 定義注解 .implements 定義接口指令 .local 指定了方法內局部變量的個數 .registers 指定方法內使用寄存器的總數 .prologue 表示方法中代碼的開始處 .line 表示java源文件中指定行 .paramter 指定了方法的參數 .param 和.paramter含義一致,但是表達格式不同
文件頭描述
.class <訪問權限修飾符> [非權限修飾符] <類名> .super <父類名> .source <源文件名稱>
- <>中的內容表示必不可缺的,[]表示的是可選擇的.
- 訪問權限修飾符即所謂的public,protected,private即default.而非權限修飾符則指的是final,abstract.
.class public final Lcom/sbbic/demo/Device; .super Ljava/lang/Object; .source "Device.java"
文件正文
- 在文件頭之后便是文件的正文,即類的主體部分,包括類實現的接口描述,注解描述,字段描述和方法描述四部分.下面我們就分別看看字段和方法的結構.(別忘了我們在Davilk中說過的方法和字段的表示)
接口描述
#interfaces .implements <接口名稱># interfaces .implements Landroid/view/View$OnClickListener;
- 普通字段:
- 訪問權限修飾符相比各位已經非常熟了,而此處非權限修飾符則可是final,volidate,transient.
#instance fields .field <訪問權限修飾符> [非權限修飾符] <字段名>:<字段類型># instance fields .field private TAG:Ljava/lang/String;
- 靜態字段
- 需要注意:smali文件還為靜態字段,普通字段分別添加#static field和#instan filed注釋.
#static fields .field <訪問權限> static [修飾詞] <字段名>:<字段類型># static fields .field private static final pi:F = 3.14f
- 直接方法
- 重點解釋一下parameter:
- parameter的個數和方法參數的數量相對應,即有幾個參數便有幾個
.parameter,默認從1開始,即p1,p2,p2….- 熟悉java的童鞋一定會記得該類型的方法有個默認的參數指向當前對象,在smali中,方法的默認對象參數用p0表示.
- 直接方法即所謂的direct methods,還記的Davilk中方法調用指令invoke-direct么。
#direct methods .method <訪問權限修飾符> [非訪問權限修飾符] <方法原型> <.locals> [.parameter] [.prologue] [.line] <代碼邏輯> .end# direct methods .method public constructor <init>()V .registers 2 .prologue .line 8 invoke-direct {p0}, Landroid/app/Activity;-><init>()V .line 10 const-string v0, "MainActivity" iput-object v0, p0, Lcom/social_touch/demo/MainActivity;->TAG:Ljava/lang/String; .line 13 const/4 v0, 0x0 iput-boolean v0, p0, Lcom/social_touch/demo/MainActivity;->running:Z return-void .end method
- 虛方法
- 虛方法的定義會和直接方法唯一的不同就是注釋不同:#virtual methods,其格式如下:
#virtual methods .method <訪問權限> [修飾關鍵詞] <方法原想> <.locals> [.parameter1] [.parameter2] [.prologue] [.line] <代碼邏輯> .end
public class MainActivity extends Activity implements View.OnClickListener { private String TAG = "MainActivity"; private static final float pi = (float) 3.14; public volatile boolean running = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onClick(View view) { int result = add(4, 5); System.out.println(result); result = sub(9, 3); if (result > 4) { log(result); } } public int add(int x, int y) { return x + y; } public synchronized int sub(int x, int y) { return x + y; } public static void log(int result) { Log.d("MainActivity", "the result:" + result); } }
#文件頭描述 .class public Lcom/social_touch/demo/MainActivity; .super Landroid/app/Activity;#指定MainActivity的父類 .source "MainActivity.java"#源文件名稱 #表明實現了View.OnClickListener接口 # interfaces .implements Landroid/view/View$OnClickListener; #定義float靜態字段pi # static fields .field private static final pi:F = 3.14f #定義了String類型字段TAG # instance fields .field private TAG:Ljava/lang/String; #定義了boolean類型的字段running .field public volatile running:Z #構造方法,如果你還納悶這個方法是怎么出來的化,就去看看jvm的基礎知識吧 # direct methods .method public constructor <init>()V .locals 1#表示函數中使用了一個局部變量 .prologue#表示方法中代碼正式開始 .line 8#表示對應與java源文件的低8行 #調用Activity中的init()方法 invoke-direct {p0}, Landroid/app/Activity;-><init>()V .line 10 const-string v0, "MainActivity" iput-object v0, p0, Lcom/social_touch/demo/MainActivity;->TAG:Ljava/lang/String; .line 13 const/4 v0, 0x0 iput-boolean v0, p0, Lcom/social_touch/demo/MainActivity;->running:Z return-void .end method #靜態方法log() .method public static log(I)V .locals 3 .parameter "result"#表示result參數 .prologue .line 42 #v0寄存器中賦值為"MainActivity" const-string v0, "MainActivity" #創建StringBuilder對象,並將其引用賦值給v1寄存器 new-instance v1, Ljava/lang/StringBuilder; #調用StringBuilder中的構造方法 invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V #v2寄存器中賦值為ther result: const-string v2, "the result:" #{v1,v2}大括號中v1寄存器中存儲的是StringBuilder對象的引用. #調用StringBuilder中的append(String str)方法,v2寄存器則是參數寄存器. invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; #獲取上一個方法的執行結果,此時v1中存儲的是append()方法執行后的結果,此處之所以仍然返回v1的 #原因在與append()方法返回的就是自身的引用 move-result-object v1 #繼續調用append方法(),p0表示第一個參數寄存器,即上面提到的result參數 invoke-virtual {v1, p0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; #同上 move-result-object v1 #調用StringBuilder對象的toString()方法 invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; #獲取上一個方法執行結果,toString()方法返回了一個新的String對象,因此v1中此時存儲了String對象的引用 move-result-object v1 #調用Log類中的靜態方法e().因為e()是靜態方法,因此{v0,v1}中的成了參數寄存器 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I .line 43 #調用返回指令,此處沒有返回任何值 return-void .end method # virtual methods .method public add(II)I .locals 1 .parameter "x"#第一個參數 .parameter "y"#第二個參數 .prologue .line 34 #調用add-int指令求和之后將結果賦值給v0寄存器 add-int v0, p1, p2 #返回v0寄存器中的值 return v0 .end method .method public onClick(Landroid/view/View;)V .locals 4 .parameter "view" #參數view .prologue const/4 v3, 0x4 #v3寄存器中賦值為4 .line 23#java源文件中的第23行 const/4 v1, 0x5#v1寄存器中賦值為5 #調用add()方法 invoke-virtual {p0, v3, v1}, Lcom/social_touch/demo/MainActivity;->add(II)I #從v0寄存器中獲取add方法的執行結果 move-result v0 .line 24#java源文件中的24行 .local v0, result:I #v1寄存器中賦值為PrintStream對象的引用out sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; #執行out對象的println()方法 invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V .line 26 const/16 v1, 0x9#v1寄存器中賦值為9 const/4 v2, 0x3#v2寄存器中賦值為3 #調用sub()方法,{p0,v1,v2},p0指的是this,即當前對象,v1,v2則是參數 invoke-virtual {p0, v1, v2}, Lcom/social_touch/demo/MainActivity;->sub(II)I #從v0寄存器中獲取sub()方法的執行結果 move-result v0 .line 28 if-le v0, v3, :cond_0#如果v0寄存器的值小於v3寄存器中的值,則跳轉到cond_0處繼續執行 .line 29 #調用靜態方法log() invoke-static {v0}, Lcom/social_touch/demo/MainActivity;->log(I)V .line 31 :cond_0 return-void .end method .method protected onCreate(Landroid/os/Bundle;)V .locals 1 .parameter "savedInstanceState" #參數savedInstancestate .prologue .line 17 #調用父類方法onCreate() invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V .line 18 const v0, 0x7f04001a#v0寄存器賦值為0x7f04001a #調用方法setContentView() invoke-virtual {p0, v0}, Lcom/social_touch/demo/MainActivity;->setContentView(I)V .line 19 return-void .end method #declared-synchronized表示該方法是同步方法 .method public declared-synchronized sub(II)I .locals 1 .parameter "x" .parameter "y" .prologue .line 38 monitor-enter p0#為該方法添加鎖對象p0 add-int v0, p1, p2 #釋放鎖對象 monitor-exit p0 return v0 .end method
- 上面兩個實例:



