Java代码:
public class MainActivityextends Activity {
public class SNChecker {
private Stringsn;
public SNChecker(String sn) {
this.sn = sn;
}
}
}
Smali:
# instance fields
.field private sn:Ljava/lang/String;
# this$0: 是 MainActivity 类型;synthetic 关键字表示它是合成的;
# this$0: 是内部类自动保留的一个指向所在外部类的引用。左边的 this 标为为父类的引用,右边的 0 表示引用的层数。最外层为0,每往里面一层右边的数值就加一。
# this$X: 型字段都被指定了 synthetic 属性,表明它们是被编译器合成的、虚构的,代码作者没有声明该字段。
.field final synthetic this$0:Lcom/droider/crackme0502/MainActivity;
# direct methods
# SNChecker 类构造函数
# public SNChecker(String sn) {
# this.sn = sn;
# }
.method public constructor <init>(Lcom/droider/crackme0502/MainActivity;Ljava/lang/String;)V
.locals 0
#p0: 隐含参数,表示 MainActivity$SNChecker 自身引用 this
.param p1, "this$0" # Lcom/droider/crackme0502/MainActivity; 第一个参数 MainActivity 引用
.param p2, "sn" # Ljava/lang/String; 第二个参数字符串 sn
.line 83
# 内部类的初始化共有以下3个步骤:
# 1. 首先保存外部类的引用到本类的一个 synthetic 字段中,以便内部类的其它方法使用。即:
# 将 MainActivity 引用赋值给 this$0
# iput-object vA, vB, field@CCCC
# 将寄存器 vA 存储的对象类型值赋给寄存器 vB 存储的实例的字段。字段类型是 CCCC
# p0->this$0 = p1
iput-object p1, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->this$0:Lcom/droider/crackme0502/MainActivity;
# 2. 然后调用内部类的父类的构造函数来初始化父类。
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
.line 84
# 3. 最后是对内部类自身进行初始化
# # p0->this$0 = p2
iput-object p2, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;
.line 85
return-void
.end method