第5章静态分析Android程序
1、 程序的主activity,每个acitiviy都是andriod程序的一个显示“页面”,主要负责数据的处理和展示工作。
2、 使用到的activity都需要在AndroidManifest.xml文件中手动声明,如声明的
activity android:label 使用到的标签和程序包
android:name="com.droider.crackme0201.MainActivity"使用到的包名
intent-filter是使用到启动的意图
category android:name="android.intent.category.LAUNCHER " 表示可以使用LAUNCHER进行启动,如果没有LAUNCHER 那这个app包启动是不可见的。
action android:name="android.intent.action.MAIN" 没有指定这个的话就无法匹配主程序的“activity”,因此程序不会出现图标。
3、 反编译出来的AndroidManifest.xml中找到主的activity后,可以去查询所有类的onCreate()方法的反汇编代码,对于绝大数的软件来说这是个代码的入口点。所有的程序都从这里开始的。
4、 Application类,在传递全局变量和在“activity”启动前做一些准备工作时需要用到application类。
5、 使用application类时需要添加一个类的继承自,andriod.app.application,然后重写它的onCreate()方法,在该方法中初始化的全局变量可以在andriod其它组件中访问,前提下必须有更public的属性。最后还需要在AndroidManifest.xml中Application标签中添加android:name属性内容,并且继承andriod.app.application类名。
6、 如何定义关键码(六种方法)
1) 信息反馈法
2) 特征函数法
3) 顺序查看法
4) 代码入注法
5) 栈跟踪法
6) Methon Prfiling
7、 Smali格式语法
.class<访问权限>[修饰关键字] <类名>
.super<父类名>
.sourec<源文件>
打开MainActivity.smali 文件
.class publicLcom/droider/crackme0201/MainActivity;
.super Landroid/app/Activity;
.source"MainActivity.java"
第1行“.class”指令指定了当前类的类名。类的访问权限为public,类名为
“Lcom/droider/crackme0201/MainActivity;”,类名开头的L是遵循Dalvik字节码的相关约定,表示后面跟随的字符串为一个类。
第2行的“.super”指令指定了当前的父类。本例中的
“Lcom/droider/crackme0201/MainActivity”的父类为“Landroid/app/Activity;”。
第3行的“.source”指令指定了当前类的源文件名。
上一章有提到dex文件格式介绍到的DexClassDef结构,这个结构描述了一个类的详细信息,该结构的第1个字段classidx就是类的类型索引,第3个字段superclassidx就是指向类的父类类型索引,第5个字段surceFileIdx就是指向类的源文件名的字符串索引。可以通过baksmali在解析dex文件时(注意:这里是反汇编),也是通过这3个字段来获取相应的类的值。
8、 smali文件中字段的声明有两种分为:
1) 静态字段 表示:static fields
2) 实例字段 表示:instance fields
9、 Smali文件中的方法的声明有两种分为:
1) 直接方法 表示:direct method
2) 虚拟方法 表示:virtual method
10、类的介绍分为外部类和内部类,samli类的结构为:
1) 例子:
MainActivity$SNChecker.smali
MainActivity是一个外部类
SNChecker是一个内部类
2) 外部类是不继承的,而内部类时继承的。
注意:在Ldalivk/annotation/EnclosingClass;与Ldalvik/annotation/InnerClass
这两个实例字段sn与this$0,一个直接方法,一个虚拟方法
Sn是字符串类型,this$0是MainActivity类型,synthetic关键字表明它是“合成”。
This$0 分解意思this是表示为父类的引用,右边的数值0表示应用的层数。
11、监听器如:button点击事件响应OnClickListener、Button的长按事件响应
OnLongClickListener、ListView列表项的点击事件响应OnItemSelected-Listenner
等。监听器的实质就是接口,对应着android系统中的
frameworks/base/core/java/android/view/View.java文件中的OnClickListener监听器
代码如下:
Public interface OnClickListener{
VoidonClick(view v);
}
设置按钮点击事件的监听器只需要实现View.OnClickListener的onClick()方法即可。在
MainActivity.smali文件,在OnCreate()方法中找到设置按钮点击事件监听器的代码如下:
OnCreate() 方法分别了调用按钮对象的setOnClickListener()方法来设置点击事件的监听器。第1个按钮事件传入一个MainActivity$1对象的引用,第2个按钮事件传入一个MainActivity$2对象的引用,查看MainActivity$1.smali代码如下:
在MainActivity$1.smali文件的开头使用了“.implements”指令指定该类实现了按钮点击事件的监听器接口,因此,这个类实现了它的OnClick()方法,这也是我们在分析程序时关心的地方。另外,程序中的注释与监听器的构造函数数都是编译器为我们自己生成的,实际分析过程中不必关心。
12、注解类 smali文件中,可以发现很多代码都使用到注解类,首先看MainActivity.smali
其中有一段
# annotations
.annotation systemLdalvik/annotation/MemberClasses;
value = {
Lcom/droider/crackme0502/MainActivity$SNChecker;
}
.endannotation
MemberClasses注解是编译时自动加上的,可以查看andriod注解源码中的MemberClasses,
代码如下:
从注释可以看出来,memberclasses是一个系统注解,作用是为父类提供一个memberclasses的列表。Memberclasses是一个子类的集合,就是一个内部类列表。
接着看MainActivity$1.smali也有一段注解如下:
可以看到对应的andriod源码路径下的EnclosingMethod.java文件,查看文件如下
其中的Method表明它作用于一个方法,而注解的value表明它位于MainActivity的onCreate()方法中。与EnclosingMethod对应的还有EnclosingClass注解,在MainActivity$SNChecker.smali文件中有如下一段代码。
EnclosingClass注解表明MainActivity$SNChecker对应着一个类,注解的value表明这个类是MainAcitivity。在往下看可以看到InnerClass,它表明是一个内部类,其中accessFlags访问标志是个枚举值如下。
Enum{
kDexVisibilityBuild = 0x00,
kDexVisibilityRuntime = 0x01,
kDexVisibilitySystem = 0x02,
};
为1时表示Runtime(运行时间)。Name为内部类的名称,本例为SNChecker。
如果注解类在声明时提供了默认值,那么程序会使用AnnotationDefault注解。打开smali/com/droider/anno目录下的MyAnnoClass.smali文件如下:
可以看到,MyAnnoClass类有一个默认值为“MyAnnoClass”。
除了介绍这些注解类外,还有Signature和Throws注解。
注意:笔者在这里不在介绍goto、for、swich反汇编第写法,会直接拿实例进行分析