深入对android的smali的指令解析

Posted 小道安全

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入对android的smali的指令解析相关的知识,希望对你有一定的参考价值。

1.普通字段读写操作

iget-object vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id对象的引用值给VBB寄存器。
iget_boolean vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id的值给vBB寄存器。
iget_wide vAA,vBB,filed_id :表示读取vAA寄存器中对象中的filed_id的值给vBB寄存器。 iget vAA,vBB,filed_id:表示vAA寄存器中对象的filed_id值给vBB寄存器。

iput-object vAA,vBB,filed_id:表示把vAA寄存器指向的对象的引用赋值给vBB寄存器中的filed_id。 iput-boolean vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器中的boolean类型。
iput_wide vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器的wide类型。
iput vAA,vBB,filed_id: 表示把vAA寄存器的值给vBB寄存器的int类型。

aget vx,vy,vz 表示从int数组获取一个int型的值到vx,对象数组的引用位于vy,需获取的元素的索引位于vz。
age-wide vx,vy,vz 表示从long/double数组获取一个long/double值到vx,vx+1,数组的引用位于vy,需获取元素的索引位于vz。

2.静态字段的读写操作

sget-object vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id对象的引用值给VBB寄存器。
sget_boolean vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id的值给vBB寄存器。
sget_wide vAA,vBB,filed_id :表示读取vAA寄存器中对象中的filed_id的值给vBB寄存器。 sget vAA,vBB,filed_id:表示vAA寄存器中对象的filed_id值给vBB寄存器。

sput-object vAA,vBB,filed_id:表示把vAA寄存器指向的对象的引用赋值给vBB寄存器中的filed_id。
sput-boolean vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器中的boolean类型。
sput_wide vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器的wide类型。
sput vAA,vBB,filed_id: 表示把vAA寄存器的值给vBB寄存器的int类型。

3.跳转指令

dalvik指令中有三种跳转指令:无条件跳转(goto),分支跳转(switch),条件跳转(if)

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-test vA, vB, +CCCC:条件跳转指令。比较vA寄存器与vB寄存器的值,如果比较结果满足就跳转到CCCC指定的偏移处。偏移量CCCC不能为0。

if-test类型的指令有以下几条:

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-testz vAA, +BBBB:条件跳转指令。拿vAA寄存器与0比较,如果比较结果满足或值为0时就跳转到BBBB指定的偏移处。偏移量BBBB不能为0。 if-testz类型的指令有以下几条:

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)”

4.比较指令

它的格式: cmpkind vAA, vBB, vCC :其中vBB寄存器与vCC寄存器是需要比较两个寄存器,比较结果放到vAA寄存器中。

Dalvik指令集共有5个比较指令 cmpl-float vAA, vBB, vCC: 比较两个单精度浮点数,如果vBB寄存器大于vCC寄存器,结果为-1,相等则结果为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: 比较两个双精度浮点数,如果VBB寄存器大于VCC寄存器,结果为1,相等结果为0,小于的话为-1。
cmp-long vAA, vBB, vCC:比较两个长整型,如果vBB寄存器大于vCC寄存器,结果为1,相等结果为0,小于结果为-1。

5.数据转换指令

它的格式: unop vA,vB:vB寄存器转换到对应数据并将结果放到vA寄存器上。

.“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”:将整型转换为短整型。

6.数据运行指令

数据运算指令包括算术运算指令与逻辑运算指令。
算术运算指令主要进行数值间如加,减,乘,除,模,移位等运算。
逻辑运算指令主要进行数值间与,或,非,抑或等运算。
数据运算指令有如下四类(数据运算时可能是在寄存器或寄存器对间进行,下面的指令作用讲解时使用寄存器来描述):

.“binop vAA, vBB, vCC”:将vBB寄存器与vCC寄存器进行运算,结果保存到vAA寄存器。

.“binop/2addr vA, vB”:将vA寄存器与vB寄存器进行运算,结果保存到vA寄存器。

.“binop/lit16 vA, vB, #+CCCC”:将vB寄存器与常量 CCCC进行运算,结果保存到vA寄存器。

.“binop/lit8 vAA, vBB, #+CC”:将vBB寄存器与常量CC进行运算,结果保存到vAA寄存器。

7.方法调用指令

.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调用实例的接口方法

8.异常处理指令

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

9.返回指令

.return-void: 表示函数从一个void返回 .return vAA: 表示函数返回一个32位非对象类型的值,返回值寄存器为8位的寄存器vAA .return-wide vAA: 表示函数返回一个64位飞对象类型的值,反黑值为8位的寄存器对vAA .return-object vAA:表示函数返回一个对象类型的值,返回值为8位寄存器vAA。

10.数据操作指令

.move vA, vB:将vB寄存器的值赋给vA寄存器,A源寄存器与目的寄存器都为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/16 vAAAA, 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寄存器,这条指令必须是异常发生时的异常处理器的一条指令。否则的话,指令无效。

.registers指令指定了在这个方法中有多少个可用寄存器。
.locals指明了在这个方法中非参寄存器的数量。

以上是关于深入对android的smali的指令解析的主要内容,如果未能解决你的问题,请参考以下文章

[Android Pro] 静态分析Android程序——smali文件解析

Android 深入系统完全讲解

Smali语法

对 Android 应用进行逆向工程时的 Smali 代码与 Java 源代码

安卓逆向学习---深入Smali文件

Android 逆向概述