深入对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文件解析