smali文件格式
普通类、抽象类、接口类或者内部类,在反编译出的代码中,都以单独的smali文件来存放
1.smali文件头3行
.class<访问权限>[修饰关键字]<类名>
.super<父类名>
.source<源文件名>
//baksmali解析dex文件时,通过这3个字段来获取相应的值
//classIdx,superclassIdx,sourceFileIdx
struct DexClassDef{
u4 classIdx; //类的类型,指向DexTypeId列表的索引
u4 accessFlags; //访问标志
u4 superclassIdx; //父类类型,指向DexTypeId列表的索引
u4 interfacesOff; //接口,指向DexTypeList的偏移
u4 sourceFileIdx; //源文件名,指向DexStringId列表的索引
u4 annotationsOff; //注解,指向DexAnnotationsDirectoryItem结构
u4 classDataOff; //指向DexClassData结构的偏移
u4 staticValuesOff;//指向DexEncodeArray结构的偏移
};
经过混淆的dex文件,反编译出来的smali代码可能没有源文件信息,“.source”行的代码可能为空。
前3行代码过后就是类的主体部分了,一个类可以由多个字段或方法组成
2.smali字段
smali文件中字段的声明使用“.field
”指令
字段有静态字段与实例字段两种
- 静态字段的声明
- # static fields
- .field <访问权限> static [修饰关键字] <字段名>:<字段类型>
- 实例字段的声明
- # instance fields
- .field <访问权限> [修饰关键字] <字段名>:<字段类型>
3.smali方法
smali文件中方法的声明使用“.method
”指令
方法有直接方法与虚方法两种
- 直接方法的声明
#direct methods
.method <访问权限> [修饰关键字]<方法原型>//方法原型描述了方法的名称、参数与返回值
<.locals> //使用的局部变量的个数
[.parameter] //指定了方法的参数,比如3个参数,就3条指令
[.prologue] //代码的开始处,混淆过的代码可能去掉了该指令
[.line] //该处指令在源代码中的行号,混淆过的代码可能去除了行号信息
<代码体>
.end method
- 虚方法的声明与直接方法相同,只是起始处的注释为“
virtual methods
”
4.smali接口
smali文件中使用“.implements
”指令指出一个类实现了接口
格式声明
- # interfaces
- .implements <接口名>
- 接口名是
DexClassDef
结构中interfacesOff
字段指定的内容
5.smali注解
smali文件中使用“.annotation
”指令指出类使用了注解
- 格式声明
#annotations
.annotation[注解属性]<注解类名>
[注解字段=值]
.end annotation
注解的作用范围可以是类、方法或字段
- 注解的作用范围是类,“
.annotation
”指令会直接定义在smali文件中 - 注解的作用范围是方法或字段,“
.annotation
”指令则会包含在方法或字段定义中
- 注解的作用范围是类,“