Android逆向学习笔记1:Dalvik指令集(3)

目录

指令类型:

空操作指令:

数据操作指令:

返回指令:

数据定义指令:

锁指令:

实例操作指令:

数组操作指令:

异常指令:

跳转指令:

比较指令:

字段操作指令:

方法调用指令:

数据转换指令:

数据运算指令:


指令类型:

参数为从目标(destination) 到 源(source);

32未字节码没有后缀,64位常规类型字节码添加-wide后缀;

特殊类型字节码可以添加 -int,-long,-float 等

例:

move-wide/from16 vAA, vBBBB

move为基础字节码(base opcode),表示这是一个基本操作;

-wide为名称后缀(name suffix),表示指令操作的数据宽度(64位);

from16为字节码后缀(opcode sufffix),表示源为一个16位的寄存器引用变量;

vAA为目的寄存器,取值范围为v0~v255;

vBBBB为源寄存器,取值范围为v0~v65535;

空操作指令:

指令解释
nop值为00,常用于对齐代码

数据操作指令:

指令解释
move vA, vB将vB寄存器的值赋予vA
move/from16 vAA, vBBBB

将vBBBB寄存器的值赋给vAA,vBBBB16位,vAA8位。

move/16 vAAAA, vBBBB将vBBBB寄存器的值赋给vAAAA,均为16位。
move-object/from16 vAA, vBBBB用于为对象赋值,剩下解释同上
move-result-wide vAA将上一个invoke类型指令操作的单字非对象结果赋给vAA。
move-result-object vAA将上一个invoke类型指令操作的对象结果赋给vAA。
move-exception vAA将一个在运行时发生的异常保存在vAA寄存器中。

返回指令:

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

数据定义指令:

用于定义程序中用到的常量,字符串,类等数据。

指令解释
const/4 vA, #+B

将数值符号扩展为32位后赋予寄存器vA

const/16 vAA,#+BBBB

将数值符号扩展为32位后赋予寄存器vAA

const vAA,#+BBBBBBBB将数值符号赋予寄存器vAA
const/high16 vAA, #+BBBB0000用于将数值右边的0扩展为32位后赋予寄存器vAA
const-wide/32 vAA, #+BBBBBBBB将数值符号扩展到64位后赋予寄存器对vAA
const-string vAA, string@BBBB通过字符串索引构造一个字符串,并将其赋予寄存器vAA
const-string/jumbo vAA, string@BBBBBBBB通过字符串索引(较大)构造一个字符串,并将其赋予寄存器vAA
const-class vAA, type@BBBB通过类型索引获取一个类引用,并将其赋予寄存器vAA

因为一个寄存器是32位,所以要先扩展到32位再赋值;-wide表示为64位,故需要两个相邻寄存器组成寄存器对。后面的/4,/16与后面的数值位数有关,一个大写字母表示4位,#+表示后面的是一个常量数字。

锁指令:

指令解释
monitor-enter vAA为指定对象获取锁
monitor-exit vAA释放指定对象的锁

实例操作指令:

指令解释
check-cast vAA, type@BBBB将vAA寄存器中的对象引用转化为指定类型,失败会抛出ClassCastException异常
instance-of vA, vB, type@CCCC判断vB寄存器中的对象引用是否可以转化成指定类型,可以vA=1,否则vA=0
new-instance vAA, type@BBBB构造一个指定类型对象的新实例,并将对象引用赋值给vAA寄存器。type指定类型不能为数组类
check-cast/jumbo vAAAA, type@BBBBBBBB与前面指令功能相同,不过指令索引和寄存器取值范围更大。另两个也可加上此后缀

数组操作指令:

指令解释
array-lengrh vA, vB获取vB中数组长度,并将其赋值给vA
new array vA, vB type@CCCC构造指定类型(type@CCCC)和大小(vB)的数组,并将值赋给vA
filled-new-array {vC, vD, vE, vF, vG}, type@BBBB构造指定类型(type@BBBB)和大小(vA)的数组并填充数组内容。vA是隐含使用的,除了指定数组大小还指定了参数的个数
filled-new-array/range {vCCCC... vNNNN}同上,只是range来指定取值范围,vC是第一个参数寄存器,N=A+C-1
fill-array-data vAA, +BBBBBBBB用指定的数据填充数组,vAA为数组引用,在指令后面会紧跟一个数据表
arrayop vAA, vBB, vCC

对vBB指定数组元素进行取值和赋值,vCC用于指定数据元素的索引,vAA用于存放需读取或设置的值。读用aget指令,赋值用aput指令;可以加上后缀,如aget-object,aput-wide等

注:蓝色为替换部分

异常指令:

指令解释
throw vAA抛出vAA中指定类型的异常

跳转指令:

指令解释
goto +AA无条件跳转到指定偏移处,偏移量AA不能为0
goto/16 +AAAA无条件跳转到指定偏移处,偏移量AAAA不能为0
packed-switch vAA, +BBBBBBBBvAA中为switch分支中需要判断的值,BBBBBBBB指向一个packed-switch-payload格式偏移表,表中的值是递增的偏移量。
sparse-switch vAA, +BBBBBBBBvAA中为switch分支中需要判断的值,BBBBBBBB指向一个sparse-switch-payload格式偏移表,表中的值是无规律的偏移量。
if-test vA, vB, +CCCC比较vA和vB的值,如果满足条件跳转到指定CCCC偏移处,不能为0。其中test可以取以下值:
if-eq 相等 if(vA==vB)
if-ne不等 vA!=vB
if-lt小于 vA<vB
if-le小于等于 vA<=vB
if-gt大于 vA>vB
if-ge大于等于 vA>=vB
if-testz vAA, +BBBB

vAA与0比较,与上面用法一致,就是后面加个z

if-gtz大于0 vAA>0

比较指令:

指令解释
cmpl-float vAA, vBB, vCC

比较两个单精度,

如vBB>vCC,vAA=-1;

vBB==vCC,vAA=0;

vBB<vCC,vAA=1。

cmpg-float vAA, vBB, vCC

比较两个单精度,

如vBB>vCC,vAA=1;

vBB==vCC,vAA=0;

vBB<vCC,vAA=-1。

cmpl-double vAA, vBB, vCC比较双精度,其余同上
cmpg-double vAA, vBB, vCC比较双精度,其余同上
cmp-long vAA, vBB, vCC

比较两个长整数

如vBB>vCC,vAA=1;

vBB==vCC,vAA=0;

vBB<vCC,vAA=-1。

字段操作指令:

普通字段指令前缀为i。

例如:读操作使用iget指令,写操作使用iput指令。

静态字段指令前缀为s。

例如:读操作使用sget指令,写操作使用sput指令。

方法调用指令:

格式:invoke-kind {vC, vD,vE,vF, vG},meth@BBBB

或 invoke-kind/range {vCCCC...vNNNN},meth@BBBB(使用range指定寄存器范围)

指令解释
invoke-virtual调用实例的虚方法
invoke-super调用实例的父方法
invoke-direct调用实例的直接方法
invoke-static调用实例的静态方法
invoke-interface调用实例的接口方法

方法调用指令必须用move-result* 指令来获取,例:

invoke-static {}, Landroid/os/Parcel;->obtain()Landroid/os/Parcel;

move-result-object v0

数据转换指令:

格式:unop vA,vB

vB中为要转换的数据,转换结果保存在vA或vA寄存器对中。

指令解释
neg-int对整形求补
not-long对长整型取反
neg-double对双精度浮点数求补
int-to-char将整形转换为字符串
int-to-double将整形转换为双精度浮点数

数据运算指令:

有四类:

1、binop vAA,vBB,vCC    vBB与vCC运算,结果保存在vAA中

2、binop/2addr vA,vB      vB与vA运算,结果保存在vA中

3、binop/lit16 vA,vB,#+CCCC   vB与常量CCCC运算,结果保存在vA中

4、binop/lit8 vAA,vBB,#+CC      vBB与常量CC运算,结果保存在vAA中

指令操作
add-type加法
sub减法
mul乘法
div相除
rem取模运算(%)
and与运算(AND)
or或运算
xor异或运算
shl左移(<<)
shr右移(>>)
ushr无符号数右移

这些基础字节码的后面还可加上-type,如:-int,-long,-float等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值