SMALI学习笔记 by vrix.yan

SMALI学习笔记 by vrix.yan

1. 基本语法

1.1 数据类型

Z,B,S,C,I,L,F,D为基本数据类型,从上表可以看出,Dalvik字节码基本类型的描述符基本上是java基本类型的首字母,除了boolean对应为Z外

1.2 对象类型

L加上类或者接口的全称表示对象类型,即Lpackage/objectName,如String类型描述符为Ljava/lang/String,包com.biyou下面的test类的类型描述符为Lcom/biyou/test

##1.3 数组类型
  基本类型的数组为”[“加上基本类型描述符来表示,一维数组前面是一个”[“,多一个维度前面多加一个”[“,比如int类型,一维是:[I,二维是:[[I,依次类推。
对象类型的数组为”[“加上对象类型表示符来表示,如String类型表示为:[Ljava/lang/String。

1.4 语法关键词

关键词	说明
.class	定义java类名
.super	定义父类名
.source	定义Java源文件名
.filed	定义字段
.method	定义方法开始
.end method	定义方法结束
.annotation	定义注解开始
.end annotation	定义注解结束
.implements	定义接口指令
.local	指定了方法内局部变量的个数
.registers	指定方法内使用寄存器的总数
.prologue	表示方法中代码的开始处
.line	表示java源文件中指定行
.paramter	指定了方法的参数
.param	和.paramter含义一致,但是表达格式不同

2. smali中的包信息

.class public Lcom/a;
.super Lcom/b;
.source "c.java"
这是一个由c.java编译得到的smail文件。他是com.a这个包下的一个类,继承自com.b这个类。

3. smali中的声明

# annotations
.annotations system Ldalvik/annotation/MemberClasses;
value={
  Lcom/a$z;
  Lcom/a$x;
}
.end annotation

这个模块是内部类的声明,a这个类中有两个成员内部类:z和x。

4. 成员变量

4.1 定义

成员变量定义格式为:
.field public/private [static][final] varName:<类型>

获取指令
iget, sget, iget-boolean, sget-boolean, iget-object, sget-object

操作指令
iput, sput, iput-boolean, sput-boolean, iput-object, sput-object
array的操作是aget和aput

指令解析
sget-object v0,Lcom/aaa;->ID:Ljava/lang/String;
获取ID这个String类型的成员变量并放到v0这个寄存器中
iget-object v0,p0,Lcom/aaa;->view:Lcom/aaa/view;
iget-object比sget-object多一个参数p0,这个参数代表变量所在类的实例。这里p0就是this

Smali代码示例1:

const/4 v3, 0x0
sput-object v3, Lcom/aaa;->timer:Lcom/aaa/timer;

相当于java代码:this.timer = null;

Smali代码示例2:

.local v0, args:Landroid/os/Message;
const/4 v1, 0x12
iput v1,v0,Landroid/os/Message;->what:I

相当于java代码:args.what = 18;
其中args为Message的实例

4.2 普通字段读写操作

前缀是i的iput-type和iget-type指令用于字段的读写操作.

指令 描述
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类型

4.3 静态字段读写操作

前缀是s的sput-type和sget-type指令用于静态字段的读写操作

指令 描述
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类型

5. smali寄存器

在虚拟机Dalvik中,方法中有两种方式定义方法中可以使用的寄存器数量。.registers 指令定义了方法中可以使用的寄存器的总数量。可以选择性的使用.locals ,该指令定义了方法中非参数寄存器的数量。寄存器的总数量应当包括方法参数所使用的寄存器的数量

v字命名		p字命名				说明
v0								the first local register
v1								the sencond local register
v2l			p0					the first paramter register
v3			p1					the second parameter register
v4			p2					the third parameter register

在smail中所有的操作都必须经过寄存器来进行。本地寄存器用v来表示,例如v0,v1,v2等。参数寄存器用p来表示,例如p0,p1,p2等。特别的一点是,p0并不一定是函数中的第一个参数,在非静态方法中,它指代“this”,p1表示函数的第一个参数。而在静态方法中,p0就是函数的第一个参数。

寄存器的表示

const/4 v0,0x1
iput-boolean v0,p0,Lcom/a;->isTrue:Z

上面的代码块首先使用了v0本地寄存器,并把值0x1存到v0中,第二句用iput-boolean这个指令把v0中的值存放到com.a.isTrue这个成员变量中,即:this.isTrue=true;。

6. 指令

6. 1 赋值指令

move(move destination)。

move va,vb               #将va=vb
move/from16 va,vb        #  va=vb   va(为8位寄存器) vb(为16位寄存器)

move-result vaa          #将上一个invoke类型指令操作的单字非对象结果返回给vaa
move-result-object vaa          #将上一个invoke类型指令操作的对象结果返回给vaa
move-exception vaa          #保存一个运行时发生的异常到vaa
throw vaa                   #抛出vaa寄存器的异常

6.2 定义指令

数据定义指令用来定义程序中用到的常量、字符串、类等。
基础字节码为const

const/4 va,#+b          #将数值符号扩展为32位后赋值给寄存器va
const/16 vaa,#+bbbb          #将数值符号扩展为32位后赋值给寄存器vaa
const va,#+bbbbbbb          #将数值赋值给寄存器va
const/high16 vaa,#+bbbb          #将数值右边零扩展为32位后赋值给寄存器vaa
const-wide/16 vaa,#+bbbb          #将数值符号扩展为64位后赋值给寄存器vaa

const-string vaa,string@bbb  #将字符串赋值给寄存器vaa
指令 描述
const/4 vA,#+B 将数值符号扩展为32后赋值给寄存器vA
const/16 vAA, #+BBBB 将数据符号扩展为32位后赋给寄存器vAA
const vAA, #+BBBBBBBB 将数值赋给寄存器vAA
const/high16 vAA, #+BBBB0000 将数值右边零扩展为32位后赋给寄存器vAA
const-wide/16 vAA,#+BBBB 将数值符号扩展为64位后赋值个寄存器对vAA
const-wide/32 vAA,#+BBBB 将数值符号扩展为64位后赋值个寄存器对vAA
const-wide vAA, #+BBBBBBBBBBBBBBBB 将数值赋给寄存器对vAA
const-wide/high16 vAA, #+BBBB000000000000 将数值右边零扩展为64位后赋给寄存器对vAA
const-string vAA,string@BBBB
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值