Smali是Davlik的寄存器语言,语法上和汇编语言类似. Davlik是基于寄存器的,就是说smali里的所有操作都必须经过寄存器来进行.
B—byte
C—char
D—double
F—float
I—int
S—short
V—void
J—long
Z—boolean
[XXX ----> array 数组
eg:
int[] ---> [I
Lxxx/yyy ----> object 对象
格式为 LpackageaName/objectName
eg:
String str --->str Ljava/lang/String;
LpackageaName/objectName$subobjectName 内部类
格式:
Func-Name (Para-Type1Para-Type2Para-Type3…)Return-Type 注意: 参数之间没有任何分隔符,返回值在最后
eg:
if-eq vA,vB,:cond_** 如果vA等于vB则跳转到:cond_**
ne 不等于
lt 小于
le 小于等于
gt 大于
ge 大于等于
eqz 等于0
nez 不等于0
ltz 小于0
gez 大于等于0
gtz 大于0
lez 小于0
- .class public Lcom/aaa;
- .super Lcom/bbb;
- .source "ccc.java"
- 是com.aaa 这个package下的一个类
- 继承自 com.bbb这个类
- 是由 ccc.java这个类编译得到的smali文件
smali中的函数和成员变量一样也分为两种:
- direct
- virtual
(1) direct method 就是 private 函数.
(2)其余的public 和 protected 函数都属于 virtual method.
eg:
invoke-direct,invoke-virtual,invole-static
invole-XXX/range (参数大于等于5个时候调用的指令)
- 用于调用static 函数
- eg:
invoke-static{},Lcom/aaa;->CheckSignature()Z
- static后面的一对大括号{},实际就是调用该方法的实例 + 参数列表, 由于方法即不需要参数也是static, 所以{}为空.
- eg:
const-string v0,"NDKLIB"
invoke-staticP{v0},Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
- static void System.loadLibrary(String) 来加载 NDK编译的so库用的方法, 就是说这里的v0 就是参数"NDKLIB"
- 用于调用父类方法用的指令, 一般用于onCreate,onDestory等方法
- 调用private 函数
- eg:
invoke-direct{p0},Landroid/app/TabActivity;->()V
- 这里init()就是定义在TabActivity中的一个private函数
- 用于调用protectd或 public函数, 同时要注意修改smali时候不要错用invoke-direct或 invoke-static
- eg:
sget-object v0,Lcom/ddd;->bbb:Lcom/ccc;
invoke-virtual{v0,v1},Lcom/ccc;->Message(Ljava/lang/Object;)V
- v0 就是 bbb:Lcom/ccc
- v1 就是 Ljava/lang/Object参数
- 当方法的参数大于等于5个时候,需要在后面加上 "/range", range表示范围,使用方法也与以上不同
- eg:
invoke-direct/range{v0..v5
},Lcom/pb/ui/TestActivity;->
h(ILjava/lang/String,Ljava/lang/String;Landroid/content/intent;I)Z
- 表示需要传递v0到v5 一共6个参数,大括号里的参数采用省略形式, 且需要连续
- Smali中需要分开来表示调用函数和返回函数结果
- 如果调用的函数返回非void, 还需要
move-result(返回基本数据类型)和move-result-object(返回对象)指令:
- eg:
const-string v0,"Eric"
invoke-static{v0},Lcom/pbi;->t(Ljava/lang/String;)Ljava/lang/String;
move-result-object v2;
- 这里 v2保存的就是调用t方法返回的字符串