android逆向之Dalvik指令集

前言

Dalvik指令语法详解
该篇文章为本人的学习笔记,如有不对之处,请指教.

附参考链接:smali文件语法参考

类型

字节码类型描述符

语法 含义
V void,只用于返回值类型
Z boolean
B byte
S short
C char
I int
J long
F float
D double
L java类类型
[ 数组类型

其中L类型可以表示Java类型中的任何类.
例如

      java.lang.String  
在smali语法中表示为:
      Ljava.lang.String;

注意后面有个分号,L类型最后的分号表示对象名结束.

[类型可以表示所有基本类型的数组. [后面紧跟基本数据类型描述符. 如[I 相当于Java中的int[],即一维数组. [[I相当于Java中的int[][],即二维数组.
三维、四维等等数值以此类推. 注意多维数组的维数最大为255个.

L[ 可以同时使用用来表示对象数组. 如[Ljava.lang.String;就表示这是一个String类型的数组.

方法及字段

方法的表现格式如下

Lpackage/name/ObjectName;->MethodName(III)Z

其中 Lpackage/name/ObjectName;应该理解为该方法所在的类,MethodName为具体方法名,(III)Z 这是方法具体的传参和返回部分,其中括号内的III为方法参数(在这里是表示三个int类型的参数),Z表示方法多维返回值(在这里返回值为boolean类型).

字段的格式和方法很像,只是方法的括号、括号里面的参数及返回值,这些字段都是没有的,后面取而代之的是字段自己的类型.字段格式如下

Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;

其中Lpackage/name/ObjectName;不用说还是该字段所在的类,FieldName为字段名,Ljava/lang/String;为字段类型.其中字段名与字段类型之间用冒号:隔开.

Dalvik指令

首先咱们来解析一条指令

move-wide/from16 vAA,vBBBB

move为基础字节码,即操作符 . wide为名称后缀,标识操作的数组为64位. from16位字节码的后缀,标识源操作数是一个16位寄存器引用变量. vAA为目的寄存器,他始终在源寄存器的前面.
vBBBB为源寄存器. 若没有wide后缀,默认为32位.

move指令

move 指令的作用是将源寄存器的值赋值给目的寄存器,即

move vA,vB

move-wide作用同上,只是赋值的为64位.</br> move-object是为对象赋值.
move-result 指令的作用是将上一个invoke类型指令的操作结果赋值给目的寄存器,即

move-result vAA

move-result-wide作用同上,只是赋值的为64位. </br> move-object同上,只是赋值为对象类型.

返回指令

return-void表示函数从一个void方法返回.
return 表示函数返回一个32位非对象的值.
return-wide 表示函数返回一个64位非对象的值.
return-object 表示函数返回一个对象类型.

数据定义

const常用来定义程序中用到是常量、字符串、类等数据.</br> const 、const/4、const/16给寄存器赋值基本数据类型.即

const/4 v1, 0x2

const-string给寄存器赋字符串,即

const-string v0, "\u60a8\u7684\u8bd5"

</br>const-class给寄存器赋值一个类引用.

锁指令

锁指令用于在多线程程序中对同一对象的操作.

monitor-enter v0

为指定的对象获取锁.

monitor-exit v0

释放指定对象的锁.

实例操作指令

  • 类型转换指令
check-cast v0,type@BBBB

v0寄存器转换成指定的类型.

  • 检查指令
instance-of v0,v1,type@BBBB

检测v1是否可以转换成指定类型,可以转换v0赋值为1,否则赋值 0.

  • 创建指令
new-instance v0,type@BBBB

构造一个指定类型的实例,并把实例对象的引用赋值给v0.类型符 type指定类型不能为数组.

数组操作指令

  • 创建数组
new-array v0,v1,type@BBBB

构造指定类型的数组,v1表示数组的大小,并将数组赋值给v0.

filed-new-array {v1,v2,v3},type@BBBB

构造数组的另一种方式,即相当于Java中的
int[] arrays= {1,2,3,4};

  • 获取数组长度
array-length v0,v1

获取v1寄存器中的数组长度,并赋值给v0寄存器.

跳转指令

  • goto指令
goto +AA

无条件跳转到指定偏移量处,偏移量不能为0.

  • switch指令
packed-switch v0,+BBBB

分支跳转,v0寄存器为switch分支中的判断值,+BBBB指向的是packed-switch-payload格式的偏移表,表中的值是有规律的.

sparse-switch v0,+BBBB

作用同上,唯一不同是偏移表中的值是无规律的.

  • if指令
    if指令格式如下
    if-eq(此处可替换) v0,v1,+BBBB
    比较两个寄存器的值,符合条件进行跳转.
操作符 作用 对应java语句
if-eq 如果v0等于v1则跳转. if(v0==v1)
if-ne 如果v0不等于v1则跳转. if(v0!=v1)
if-lt 如果v0小于v1则跳转. if(v0<v1)
if-gt 如果v0大于v1则跳转. if(v0>v1)
if-le 如果v0小于等于v1则跳转. if(v0<=v1)
if-ge 如果v0大于等于v1则跳转. if(v0>=v1)
    if-eq(此处可替换) v0,+BBBB

用寄存器中的值和0进行比较,符合跳转跳转.

操作符 作用 对应java语句
if-eqz 如果v0等于0则跳转. if(v0==0)
if-nez 如果v0不等于0则跳转. if(v0!=0)
if-ltz 如果v0小于0则跳转. if(v0<0)
if-gtz 如果v0大于0则跳转. if(v0>0)
if-lez 如果v0小于等于0则跳转. if(v0<=0)
if-gez 如果v0大于等于0则跳转. if(v0>=0)

比较指令

用于比较两个寄存器的值(浮点型或长整型),比较结果放到v0寄存器中.
格式

cmpl-float(此处可替换) v0,v1,v2
操作符 作用
cmpl-float 如果v1小于v2则结果为1,相等则结果为0,大于则结果为-1.
cmpg-float 如果v1大于v2则结果为1,相等则结果为0,小于则结果为-1.
cmpl-double 如果v1小于v2则结果为1,相等则结果为0,大于则结果为-1.
cmpg-double 如果v1大于v2则结果为1,相等则结果为0,小于则结果为-1.
cmp-long 如果v1大于v2则结果为1,相等则结果为0,小于则结果为-1.

字段操作指令

字段操作指令分两大类:普通字段和静态字段,普通字段指令的前缀为i,静态字段指令的前缀为s.
字段的读操作指令为get,写操作指令为put,因此普通字段的操作指令为iget,iput.静态字段的操作指令为sget,sput.
指令格式如下

.line 16
iput-object p1, p0, Lcom/view/dialogapplication/PhoneInfo;->context:Landroid/content/Context;

上面是一段iput指令代码,它所对应的java代码如下

  this.context = context;

没错,它就会一个简单的赋值context的代码;
由此,可以看出来, p1是要赋值的context,p0是源,而后面的第三个参数

Lcom/view/dialogapplication/PhoneInfo;->context:Landroid/content/Context;

可以看出来是p1的字段名.

此外还有一组以a为前缀的的操作指令,分别为aputaget,不过它们应该不算在字段的范畴了,应该为数组操作范畴,但因为也是和读写操作有关,所以就写在这里了,具体格式如下

aput-object  v2,v1,v0

其具体作用为将v2的值放入到v1数组的v0位置处.所以可以看出,v2为要放入的值,v1代表着存放v2值的数组,而v0则是v2要存放在数组的位置,即v0为index(数组角标).

方法调用指令

方法调用指令赋值调用类实例(也就是对象)的方法,它的基础指令为invoke.指令格式如下

invoke-virtual(名称后缀可替换) {v0,v1},method@BBBB(具体的方法)

其中{v0,v1}大括号中第一位放的是调用方法的对象,之后的为方法中的参数.若没有参数则只需传入调用方法的对象,即{v0}.

指令 作用
invoke-virtualinvoke-virtual/range 调用实例的虚方法.
invoke-superinvoke-super/range 调用实例父类的方法.
invoke-directinvoke-direct/range 调用实例的直接方法.
invoke-staticinvoke-static/range 调用实例的静态方法.
invoke-interfaceinvoke-interface/range 调用实例的接口方法.

数字转换指令

数据转换指令用于将一种类型的数值转换成另一种类型.格式如下

neg-int(可替换如下) v0,v1

指令中,v1存放需要转换的数据,v0存放转换后的结果.

指令 作用
neg-int 对整型输求补.
not-int 对整型输求反.
neg-long 对长整型数求补.
not-long 对长整型数求反.
neg-float 对单精度浮点型数求补.
neg-double 对双精度浮点数求补.
int-to-long 将整型数转换为长整型.
int-to-float 将整型数转换为单精度浮点型.
int-to-double 将整型数转换为双精度浮点型.
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 将整型转换为短整型.

数据运算指令

数据运算指令分为算术运算指令和逻辑运算指令,即 加、减、乘、除、取模、位移及与、或、非、异或等.
格式如下

add-int(可替换如下) v0,v1,v2

指令中,将v1v2进行运算,结果存到v0.

指令 作用
add-type v1v2进行加法运算,即v1+v2.
sub-type v1v2进行减法运算,即v1-v2.
mul-type v1v2进行乘法运算,即v1*v2.
div-type v1v2进行除法运算,即v1/v2.
rem-type v1v2进行取模运算,即v1%v2.
and-type v1v2进行与运算,即v1 AND v2.
or-type v1v2进行或运算,即v1 OR v2.
xor-type v1v2进行异或运算,即v1 XOR v2.
shl-type v1进行(有符号位)左移v2位,即v1<<v2.
shr-type v1进行(有符号位)右移v2位,即v1>>v2.
ushr-type v1进行(无符号位)右移v2位,即v1>>v2.

其中后面的-type可以是-int、-long、-float、-double.

至此,Dalvik指令集基本就都介绍完了
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容