|
|
教你读懂Smali代码(一)
类型
在Java中类型分为基本类型和引用类型
基本类型共有9个,它们在Smali中的对应关系是:
| Java | Smali | | void | V | | boolean | Z | | byte | B | | short | S | | char | C | | int | I | | long | J | | float | F | | double | D |
其中除了boolean对应Z,long对应J,其它都是对应首个字母大写,还是很好记的
对于引用类型,我在上一篇文章中也提到过,在Smali中都是用L包名路径/类名;表示,例如Android中的TextView类,它的包名是android.widget,如果你要在Smali中表示这个类,就要写成Landroid/widget/TextView;
Smali中通过在类型前面加[来表示该类型的数组,例如[I表示int[],[Ljava/lang/String;表示String[],如果要表示多维数组,只需要增加[的数量,例如[[I表示二维数组int[][]
方法
Smali中定义方法的语法是:
.method 描述符 方法名(参数类型)返回类型
方法代码...
.end method
其中参数类型可以有0个或多个,返回类型必须是一个,当要表达多个参数类型时,只需简单地将它们连接到一起,例如 (int, int, String) 表示为 (IILjava/lang/String;)
方法代码是最复杂的部分,将在后面的文章中慢慢介绍
调用方法
Smali中必须以非常详细的形式指定要调用的方法,包括类名、方法名、参数类型和返回类型,其具体形式是:类名->方法名(参数类型)返回类型
例如
System.out.println("Hello world");
其中out是System的一个静态字段,它的类型是PrintStream,println是PrintStream中的一个方法
所以在上一篇的例子中,最后调用println方法是通过:
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
后面那部分正是方法println的完整表达形式
字段
Smali中定义方法的语法是:
.field 描述符 字段名:字段类型
例如Java代码中定义了text字段:
public String text;
其对应的Smali代码是:
.field public text:Ljava/lang/String;
当一个字段是static和final(即静态常量)且它的类型是基本类型时,可以直接为它赋值:
.field public static final ID:I = 0x7f0a0001
如果定义的字段包含注解,那么语法是:
.field XXXXX
{注解列表}
.end field
引用字段
和调用方法类似,在引用一个字段时,同样需要用非常详细的形式指定字段,其具体形式是:类名->字段名:字段类名
例如
System.out.println("Hello world")
在调用println方法前需要现将System类的字段out放到寄存器v0中
也就是下面这句代码:
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
后面那部分正是字段out的完整表达形式
教你读懂Smali代码(三) |
-
查看全部评分
总评分:好评 +2
金币 +4
|