Android 程序是基于 Dalvik 虚拟机运行的,在逆向安卓程序时,一般会选择 Smali 的语法格式。大部分的 Dalvik 指令和 Smali 语法都是很容易理解的,但是也有一些不是那么直观的指令和语法,下面结合具体例子加以理解。
这个例子是我们 Android 开发课中我写的一次作业,要是雷同就只能说太巧了...
其对应的 Smali 语法如下:
第 48 行表明以下是描述虚函数的
第 49 行将 onCreate 标识为带有一个 Bundle 类型参数的 protected void 方法,其中最后一个字母 V 代表void
第 50 行表明该方法有 7 个局部变量
第 51 ~ 54 行说明了形参 p1 的名字为 saveInstanceState
,而且它是用 @android/support/annotation/Nullable
的标注标注的。留意到这里是 p1,因为 p0 通常用于指代 this
第 56 行表明以下是函数的主体
第 58 行使用的 Dalvik 指令是 invoke-super
,后面紧跟的大括号中有两个参数 p0 和 p1,由于 onCreate 函数不是静态的(指令本身也不是用于调用静态函数),因此 p0 是指调用 onCreate 函数的对象,在这里就是 this
;紧接着的 Landroid/support/v7/app/AppCompatActivity
表明 p0 此时的类型是 AppCompatActivity,这很好理解,因为 this
是 MainActivity 的引用,而 MainActivity 继承于 AppCompatActivity;
第 61 行将 v4 的值赋为 0x7f040019,这是一个资源的编号,在这里就是 R.layout.layout
第 63 行的 invoke-virtual
表明调用了一个虚函数,调用者为 p0,此时 p0 的身份为 MainActivity,调用的函数为 setContentView
,该函数以一个整数(v4)为参数,并返回 void
下面看一个涉及内部类的例子
其对应的 Smali 语法如下:
第 146 行将 v4 的值赋为 "\u63d0\u793a",即中文 “提示”
第 148 ~ 149 行用 v0(局部变量 alertDialog)调用 setTitle 函数,该函数返回一个与 alertDialog 同为 AlertDialog.Builder 类型的对象,因此在源代码中可以在调用完 setTitle 后马上调用 setPositiveButton
第 151 行将 148 ~ 149 行中返回的 AlertDialog.Builder 类型的对象赋给 v4,方便 setPositionButton 的调用
第 155 行实例化了一个 MainActivity$2 的对象,并赋给 v6;这里的 $2 是指在 MainActivity 中的一个匿名内部类,对应的是源代码中第 35 行 setPositionButton 的第二个参数,该参数实现了一个匿名类,并实例化了一个该类的对象,这个类的实现细节保存在 MainActivity$2.smali 中,其中较为重要的细节如下:
可以看到,在这个匿名类中使用了 Toast 来输出信息
第 157 ~ 158 行将 155 行的对象进行初始化
第 160 ~ 162 行用 v4(AlertDialog.Builder 类型) 以 v5(CharSequence 类型) 和 v6(DialogInterface.OnClickListener 类型) 作为参数调用了 setPositiveButton 函数
这个例子主要是用于熟悉 Smali 语法,涵盖的 Dalvik 指令不多,但是稍微没那么直观,先记下来以后还可以回来看