Smali 文件结构及常见指令

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);
}

相关工具及资料