Smali 是 Android Dalvik 虚拟机的汇编语言,用于表示 .dex 文件中的字节码。理解 smali 代码需要掌握其语法和指令集。
Smali 文件结构
一个 smali 文件通常对应一个 Java 类,文件扩展名为 .smali。其基本结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| .class public Lcom/example/MyClass; .super Ljava/lang/Object; .source "MyClass.java"
.field private myField:I
.method public constructor <init>()V .registers 1 return-void .end method
|
基本语法
类声明
1
| .class public Lcom/example/MyClass;
|
- public 表示类的访问修饰符。
- Lcom/example/MyClass; 是类的完整名称,L 表示类,; 是结束符。
字段定义
1
| .field private myField:I
|
- private 是访问修饰符。
- myField 是字段名称。
- I 是字段类型(int)。
方法定义
1 2 3 4 5
| .method public myMethod()V .registers 2 return-void .end method
|
- public 是访问修饰符。
- myMethod 是方法名称。
- ()V 表示方法签名(无参数,返回值为 void)。
- .registers 2 表示方法使用的寄存器数量。
常见指令
数据操作
- const/4 v0, 0x1:将常量 1 存入寄存器 v0。
- move v0, v1:将寄存器 v1 的值复制到 v0。
方法调用
- invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z:调用 String.equals 方法。
- invoke-static {}, Ljava/lang/System;->currentTimeMillis()J:调用静态方法。
控制流
- if-eqz v0, :label:如果 v0 为 0,跳转到 :label。
- goto :label:无条件跳转到 :label。
返回
- return-void:返回 void。
- return v0:返回寄存器 v0 的值。
数据类型
Smali 类型 |
Java 类型 |
V |
void |
Z |
boolean |
B |
byte |
S |
short |
C |
char |
I |
int |
J |
long |
F |
float |
D |
double |
Ljava/lang/String; |
String |
5. 示例分析
Smali 代码
1 2 3 4 5 6 7
| .method public static main([Ljava/lang/String;)V .registers 3 const-string v0, "Hello, World!" sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V return-void .end method
|
Java 代码
1 2 3 4
| public static void main(String[] args) { String v0 = "Hello, World!"; System.out.println(v0); }
|
相关工具及资料