Smali文件详解

435 阅读4分钟

往期推荐

了解C语言

Java层反调试

实战讲解:Crakeme01

实战:AliCrackme

Anti Debug:实战讲解

Smali是Dalvik VM内部执行的核心代码,是Dalvik自己的语法规范。在反编译出的代码中,无论是普通类、抽象类、接口类或者内部类,它们都以单独的Smali文件来存放。每个 smali文件都由若干条语句组成,所有的语句都遵循着一套语法规范。

1.描述类信息

在打开Smali文件时,它的头三行描述了当前类的一些信息:

.class < 访问权限> [ 修饰关键字] < 类名>

.super < 父类名>

.source <源文件名>;如下所示:

.class指令表示当前类名,类的访问权限是public,类名为LHelloWorld,类开头的L表示后面跟随的字符串是一个类。

.super指定了当前类所继承的父类,后面指的就是这个父类的类名,L表示后面跟的字符串是一个类。

.source行代码为空。经过混淆的dex文件,反编译出来的Smali代码可能没有源文件信息,因此source行的代码可能为空。

Smali文件类的主体部分:一个类由字段和方法组成。.field字段声明,字段分两类:静态字段和实例字段。

2.静态字段

1.静态字段格式:

static fields

.field < 访问权限> static [ 修饰关键字]< 字段名>:< 字段类型>

baksmali在生成smali文件时,会在静态字段声明的起始处添加注释”static fields”,注释是以#开头。

访问权限包括:private、protected、public(三者之一)

修饰关键字:字段的其他属性,例如,final

例如:

3.实例字段

实例字段相比于静态字段少了一个static的静态声明,其他均相同。

1.实例字段格式:

instance fields

.field < 访问权限> [ 修饰关键字] < 字段名>:< 字段类型>

例如:

smali的方法声明使用的.method指令,方法分为直接方法和虚方法两种。

4.直接方法

直接方法是指该类中定义的方法。

1.直接方法的格式:

direct methods

.method <访问权限> [ 修饰关键字] < 方法原型>

<.registers>

<.locals>

[.param]

[.prologue]

[.line]

<代码体>

.end method

#direct methods :是baksmali添加的注释。

访问权限和修饰关键字:与字段相同。

方法原型:描述了方法的名称、参数与返回值。

.registers:指令指定了方法中寄存器的总数,这个数量是参数和本地变量总和。

.param :表明了方法的参数,每个.param指令表示一个参数,方法使用了几个参数就有几个.parameter指令。

.prologue:指定了代码的开始处,混淆过的代码可能去掉了该指令。

.line:指明了该处代码在源代码中的行号,同样,混淆后的代码可能去掉了行号。

.local:使用这个指定表明方法中非参寄存器。

例如:

5.虚方法

虚方法:是指从父类中继承的方法或者实现的接口的方法,它的声明跟直接方法相同,只是起始的初始为“virtual methods”。

1.虚方法的格式:

virtual methods

.method <访问权限> [ 修饰关键字] < 方法原型>

<.registers>

<.locals>

[.param]

[.prologue]

[.line]

<代码体>

.end method

例如:

6.接口

如果一个类实现了一个接口,那么会在smali文件中用.implements指令指出。

1.接口的格式:

interfaces

.implements < 接口名>

#interfaces:注释。

.implements :接口关键字。

接口名:DexClassDef 结构中interfacesOff 字段指定的内容。

例如:

7.注解

如果一个类使用了注解,那么Smali中会使用.annotation指令。

1.注解的格式:

annotations

.annotation [ 注解属性] < 注解类名>

[ 注解字段 = 值]

.end annotation

2.注解的作用范围可以是类、方法或字段:

如果注解的作用范围是类,“.annotation” 指令会直接定义在Smali 文件中;

如果是方法或字段,“.annotation ”指令则会包含在方法或字段定义中。

例如:

(1)注解类

(2)注解方法

(3)注解字段

小结:

今天掌握了所有Smali相关符号含义的解析,包括:描述类的信息(class< 访问权限> [ 修饰关键字] < 类名>、super< 父类名>、source<源文件名>);静态字段# static fields(.field < 访问权限>static [ 修饰关键字]< 字段名>:< 字段类型>)实例字段# instance fields(.field < 访问权限> [ 修饰关键字] < 字段名>:< 字段类型>)直接方法,它指的是该类中定义的方法;虚方法,、接口以及注解。

如果你也对安卓逆向感兴趣,可以扫描如下二维码,或者微信搜索【宸道移动安全团队】,关注有惊喜哦!

qq:3543756281 •