【逆向教程】读懂Smali代码②

类型

在Java中类型分为基本类型和引用类型

基本类型共有9个,它们在Smali中的对应关系是:

JavaSmali
voidV
booleanZ
byteB
shortS
charC
intI
longJ
floatF
doubleD

其中除了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");
其中outSystem的一个静态字段,它的类型是PrintStreamprintlnPrintStream中的一个方法

所以在上一篇的例子中,最后调用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的完整表达形式

© 版权声明
THE END
喜欢就支持以下吧
点赞130
分享
评论 抢沙发