Smali 语法

1、基础

1、变量类型

B—byte
C—char
D—double
F—float
I—int
S—short
V—void
J—long
Z—boolean

2、运算符

Smali 含义 符号
eq equals ==
ne not equals !=
lt less than <
gt bigger than >
le less and equals <=
ge bigger and equals >=
eqz equals zero =0
nez not equals zero !=0
ltz less than zero <0
btz bigger than zero >0
gez bigger and equals zero >=0
lez less and equals zero <=0

3、关键字

// L 代表一个对象类型
//.class 表示一个类,pulic 代表公有 ,后面是全包名
// ; 分号作为语句结尾 
.class public Lcom/zk/demo/MainActivity;
//.super 表示父类
.super Landroid/support/v7/app/AppCompatActivity; 
//.source 代表类所在的文件名
.source "MainActivity.java"
// # 声明
// .implements (实现接口 一般在文件顶部) <实现的接口>
# interfaces
.implements Ljava/lang/Runnable;

// 直属方法 当前类所有的,不可被覆写的方法 一般是 私有/静态方法、及静态构造方法
# direct methods
// 虚方法 当前类实现,但是可以被 子类覆写的方法,多为 public/protect/inteface 的方法
# virtual methods

//代码所属行数
. line
// 局部变量 寄存器申请数
.locals N 
// 方法的形参 非静态参数 p0 代指this ; p1 代指第一个形参 ,静态函数 p0 代指第一个参数
// .param [形参变量][形参名][形参类型]
.param p1, "msg"    # Ljava/lang/String;
//方法开始位置
.prologue
// 结束位置
.end field / mehod / annotation
//创建实例 new-instance v1, Lcom/example/zhaokai/demo/Test;
new-instance
// 获取 变量
sget-object
// 赋值
iput-object

4、字段

// # 后面跟声明 标识接下来的类型 
# instance fields
.field private isPayTest:Z
# static fields

// .field 表示后面跟的是字段类型,结合上面语句代表 当前字段
//REQUEST_CODE 是个私有静态的int类型
// : 前面是字段名称,后面则是字段类型 ,= 后面则是字段的赋值
// 格式 .field <访问权限> <静态> <不可更改> <变量名> : <变量类型> = <赋值>  
.field private static final REQUEST_CODE:I = 0x186b4      

5、方法

//.method [方法权限]{[abstract/static/final] [varargs] }[方法名](形参类型 形参类型)[返回值类型]
.method protected setMsg(Ljava/lang/String;Ljava/lang/String;)V
    //方法内局部变量数(不包含形参)
    .locals 1
    .param p1, "msg"    # Ljava/lang/String;
    // 形参 可变形参 用数组标识 #[Ljava/lang/String;
    // 行数
    .line 31
    //…… 执行方法
    .line 32
    return-void 
    //无返回值 returen-object 返回指定值
//方法结束
.end method

6、局部变量

//本地寄存器(local register,非参寄存器)用v开头数字结尾的符号来表示,如v0、v1、v2、…,
// locals 1  对应一个本地寄存  v0
//参数寄存器(parameter register)用p开头数字结尾的符号来表示,如p0、p1、p2、…,p0 默认为this

7、赋值获取

sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
//获取参数值 变量名,对象类型 -> 获取方法 : 获取对象类型
iput-boolean v0, p0, Lcom/example/zhaokai/demo/Test;->isTest:Z
//给参数赋值
sget/sput: static 对已标识的静态字段执行已确定的对象静态字段运算
iget/iput: instance 对已标识的字段执行已确定的对象实例字段运算
aget/aput: array 在给定数组的已标识索引处执行已确定的数组运算

sget-类型 [wide/boolean/object/byte/char/short]

8、方法执行

//返回值
move-result-object v3
//调用指定的方法。所得结果(如果有的话)可能与紧跟其后的相应 move-result* 变体指令一起存储。

invoke-virtual {v0, v1}, Ljava/io/PrintStream;->print(Ljava/lang/String;)V
//使用 invoke-virtual 调用正常的虚方法(该方法不是 private、static 或 final,也不是构造函数)

invoke-direct {v0, v1}, Lcom/example/zhaokai/demo/Test;->print(Ljava/lang/String;)Ljava/lang/String;
//invoke-direct 用于调用非 static 直接方法(也就是说,本质上不可覆盖的实例方法,
// 即 private 实例方法或构造函数)

invoke-static {v2}, Lcom/example/zhaokai/demo/Test;->setVERSION(Ljava/lang/String;)V
//invoke-static 用于调用 static 方法(该方法始终被视为直接方法)。

invoke-interface {v0}, Ljava/lang/Runnable;->run()V
//invoke-interface 用于调用 interface 方法,也就是说,在具体类未知的对象上,使用引用 interface 的 method_id。

invoke-super {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;
move-result-object v0
//invoke-super 来调用在该接口上定义的该方法的最具体、未被覆盖版

9、常用语句

//日志输出
const-string v2, "push"
.local v2, "tag":Ljava/lang/String;
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

10、smali 文件结构

// 当前类名:.class public Lcom/kwai/game/ddz/MainActivity;
// 父类:.super Lcom/unity3d/player/UnityPlayerActivity;
// 文件名:.source "MainActivity.java"
# static fields
//静态字段  finish 会赋值、其他则只声明

# instance fields
//实例字段

# direct methods
.method static constructor ()V
//静态构造函数<静态代码块><静态初始化>

.method public constructor ()V
//实例构造函数

//其他方法
# virtual methods

你可能感兴趣的:(Smali 语法)