Dalvik指令

安卓逆向学习交流群:692903341
Dalvik指令:
基础字节码-名称后缀/字节码后缀 目的寄存器 源寄存器
名称后缀是wide,表示数据宽度为64位
字节码后缀是from16,表示源寄存器为16位

空操作指令:
nop :空操作指令的助记符 为nop。它的值为00,通常nop指令被用来作对齐代码之用,无实际操作。

数据操作指令:
move v0, v1:将v0寄存器的值赋给v1寄存器,源寄存器与目的寄存器都为4位。
move/from16 v0, v1:将v1寄存器的值赋给v0寄存器,源寄存器为16位,目的寄存器为8位。
move/16 v0, v1:将v1寄存器的值赋给v0寄存器,源寄存器与目的寄存器都为16位。
move-wide v0, v1:为4位的寄存器对赋值。源寄存器与目的寄存器都为4位。
move-wide/from16 v0, v1 与“move-wide”相同。
move-object v0, v1:为对象赋值。源寄存器与目的寄存器都为4位。
move-object/from16 v0, v1:为对象赋值。源寄存器为16位,目的寄存器为8位。
move-object/16 v0 v1:为对象赋值。源寄存器与目的寄存器都为16位。
move-result v0:将上一个invoke类型指令操作的单字非对象结果赋给v0寄存器。
move-result-wide v0:将上一个invoke类型指令操作的双字非对象结果赋给v0寄存器。
move-result-object v0:将上一个invoke类型指令操作的对象结果赋给v0寄存器。
move-exception v0:保存一个运行时发生的异常到v0寄存器,这条指令必须是异常发生时的异常处理器的一条指令。否则的话,指令无效。

返回指令:
return-void:表示函数从一个void方法返回。
return:表示函数返回一个32位非对象类型的值,返回值寄存器为8位的寄存器。
return-wide:表示函数返回一个64位非对象类型的值,返回值为8位的寄存器。
return-object:表示函数返回一个对象类型的值。返回值为8位的寄存器。

数据定义指令:
const/4 v0, #1:将数值符号扩展为32位后赋给寄存器v0。
const/16 v0, #+1:将数据符号扩展为32位后赋给寄存器v0。
const-wide/16 v0, #1:将数值符号扩展为64位后赋给寄存器对v0。
const-wide/32 v0, #1:将数值符号扩展为64位后赋给寄存器对v0。
const-wide v0, #+1”:将数值赋给寄存器对v0。
const-string v0 string@s:通过字符串索引构造一个字符串并赋给寄存器v0。
const-class v0, type@s:通过类型索引获取一个类引用并赋给寄存器v0。

实例操作指令:
check-cast v0, type@s:将v0寄存器中的对象引用转换成指定的类型,如果失败会抛出ClassCastException异常。如果类型s指定的是基本类型,对于非基本类型的0来说,运行时始终会失败。
instance-of v0 v1, type@s:判断v1寄存器中的对象引用是否可以转换成指定的类型,如果可以v0寄存器赋值为1,否则v0寄存器赋值为0。
new-instance v0, type@s:构造一个指定类型对象的新实例,并将对象引用赋值给v0寄存器,类型符type指定的类型不能是数组类。

数组操作指令:
array-length v0, v1:获取给定v1寄存器中数组的长度并将值赋给v0寄存器,数组长度指的是数组的条目个数。
new-array v0, v1, type@s:构造指定类型(type@s)与大小(v1)的数组,并将值赋给v0寄存器。
filled-new-array {v3, v4, v5, v6, v7},type@s:构造指定类型(type@s)与大小(v0)的数组并填充数组内容。v0寄存器是隐含使用的,除了指定数组的大小外还指定了参数的个数,v3~v7是使用到的参数寄存序列。
filled-new-array/range {v3 …vn}, type@s:指令功能与“filled-new-array”相同,只是参数寄存器使用range字节码后缀指定了取值范围 ,v3是第一个参数寄存器,n = 0 +3 -1。
fill-array-data v0, +1:用指定的数据来填充数组,v0寄存器为数组引用,引用必须为基础类型的数组,在指令后面会紧跟一个数据表。

异常指令:
throw v0:抛出v0寄存器中指定类型的异常。

跳转指令:
goto:无条件跳转到指定偏移处,偏移量不能为0。
packed-switch :分支跳转指令。寄存器为switch分支中需要判断的值,指向一个packed-switch-payload格式的偏移表,表中的值是有规律递增的。
if-eq:如果v0等于v1则跳转。Java语法表示为 if(v0 == v1)。
if-ne:如果v0不等于v1则跳转。Java语法表示为 if(v0 != v1)。
if-lt:如果v0小于v1则跳转。Java语法表示为 if(v0< v1)。
if-le:如果v0小于等于v1则跳转。Java语法表示为 if(v0<= v1)。
if-gt:如果v0大于v1则跳转。Java语法表示为 if(v1> v1)。
if-ge:如果v0大于等于v1则跳转。Java语法表示为 if(v1>= v0)。

比较指令:
cmp-long(类型):比较两个长整型数。如果v0寄存器大于v1寄存器,则结果为1,相等则结果为0,小则结果为-1。
cmpl-float(类型):比较两个单精度浮点数。如果v0寄存器大于v1寄存器,结果为-1,相等则结果为0,小于的话结果为1。
cmpg-double(类型):比较两个单精度浮点数。如果v0寄存器大于v1寄存器,则结果为1,相等则结果为0,小于的话结果为-1。

字段操作指令:
普通字段指令的指令前缀为i,如对普通字段读操作使用 iget 指令,写操作使用 iput 指令;静态字段的指令前缀为s,如对静态字段读操作使用 sget 指令,写操作使用 sput 指令。
普通字段操作指令有:iget,iget-wide,iget-object,iget-boolean,iget-byte,iget-char,iget-short,iput,iput-wide,iput-object,iput-boolean,iput-byte,iput-char,iput-short。
静态字段操作指令有:sget,sget-wide,sget-object,sget-boolean,sget-byte,sget-char,sget-short,sput,sput-wide,sput-object,sput-boolean,sput-byte,sput-char,sput-short。

方法调用指令:
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 调用实例的接口方法。

数据转换指令:
neg-int(类型):对整型数求补。
not-int(类型):对整型数求反。
int(类型)-to-long(类型):将整型数转换为长整型。

数据运算指令:
add-type:v0寄存器与v1寄存器值进行加法运算(v0 + v1)。
sub-type:v0寄存器与v1寄存器值进行减法运算(v0 - v1)。
mul-type:v0寄存器与v1寄存器值进行乘法运算(v0 * v1)。
div-type:v0寄存器与v1寄存器值进行除法运算(v0 / v1)。
rem-type:v0寄存器与v1寄存器值进行模运算(v0 % v1)。
and-type:v0寄存器与v1寄存器值进行与运算(v0 & v1)。
or-type:v0寄存器与v1寄存器值进行或运算(v0 | v1)。
xor-type:v0寄存器与v1寄存器值进行异或运算(v0 ^ v1)。
shl-type:v0寄存器值(有符号数)左移v1位(v0 << v1 )。
shr-type:v0寄存器值(有符号)右移v1位(v0 >> v1)。
ushr-type:v0寄存器值(无符号数)右移v1位(v0 >>> v1)。

猜你喜欢

转载自blog.csdn.net/YJJYXM/article/details/103122534