第4章 android可执行文件
1、 andriod程序主要大多数时间在和DEX打交道,只要掌握了DEX文件的格式才能更加深入地理解andriod系统,才能对软件安全有更深刻的了解。
2、 APK包其实就是ZIP压缩包,使用ZIP压缩软件可以多APK进行解压。
3、 APK的组成由一些图片集资源和其他的文件组成,并且每个APK包都包含一个classes.dex.
4、 Classes.dex文件就是Dalvik虚拟机的可执行文件简称Dalvik可执行文件。
5、 Android打包方式有2种:
1)一种使用Android studio进行打包。
2)二种使用Ant工具进行打包。
前一种打包方式:
打包方式分为7步:
1、打包资源的工具aapt位于 android-sdk下的platform-tools目录下该工具的源码在Android系统源码的/root/android-4.0.3_r1/frameworks/base/tools/aapt(注意:每个文件路径设置不一样)。生成的过程主要是调用了aapt源码目录下的Resource.cpp文件中的buildResources()函数,该函数首先检查AndroidManifest.xml的合法性,然后对res目录下的资源子目录进行处理,处理的函数为makeFileResources(),处理的内容包括资源文件名的合法性检查,向资源表的table添加条目等,处理完后调用compileResourceFile()函数编译res与asserts目录下的资源并生成resource.arsc文件,compileResourceFile()函数位于aapt源码目录的ResourceTable.cpp文件中,该函数最后会调用parseAndAddEntry()函数生成R.java文件,完成资源编译后,接下来调用comileXmlFile()函数对res目录的子目录下的xml文件分别进行编译,这样处理过的xml文件就简单的被“加密”了,最后将所有的资源与编译生成的resources.arsc文件以及“加密”过的AndroidManifest.xml文件打包压缩resources.ap_文件(注意:Ant工具命令行编译则会生成与build.xml中“project name”指定的属性同名的ap_文件)。
2、处理aidl文件,生成相应的java文件。对于没有使用到aidl的Android工程,这一步可以跳过。这一步使用到的工具为aidl,位于sdk目录下的platform-tools。Aidl工具解析接口定义文件并生成相应的java代码供程序调用。(注意:如果想查看源码位于, /root/android-4.0.3_r1/frameworks/base/tools/aidl目录下)。
3、编译工程源码,生成相应的class文件。这一步调用javac编译工程src目录下所有的java源文件,生成的class文件位于工程的bin\classes目录下,假定编译工程源代码时程序是基于android sdk的,在实际过程中会使用andriod ndk来编译native代码,因此如果可以话,这一步还需要ndk编译代码。
4、转换所有的class文件,生成classes.dex文件。签名曾多次提到这个,andriod系统Dalvik虚拟机的可执行文件为DEX格式,程序运行所需要的classes.dex就是在这一步生成的,使用的到的工具dx,它位于/root/android-sdk/build-tools/23.0.2目录下,dx工具主要的工作是将java字节码转换为Dalvik字节码、压缩常量池、消除冗余信息等。
5、打包生成APK文件。打包的工具为apkbuilder,它的工具路径为/root/android-sdk/tools,
实际调用的是/root/android-sdk/tools/lib/sdklib.jar文件中的com.android、sdklib.build、ApkBuilderMain类。对应的andriod源码的目录路径为:
/android-4.0.3_r1/sdk/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ ApkBuilderMain.java文件,它构建了一个ApkBuilder类,然后以包含resources.arsc的文件为基础生成apk文件,这个文件为ap_结尾的文件,接着调用addSourceFolder()函数添加工程的资源,addSourceFolder()会调用processFileForResource() 函数往apk文件中添加资源,处理的内容包括res目录与assets目录中的文件,添加完资源后调用addResourcesFromJar()函数往apk文件中写入依赖库,接着调用addNativeLibraries()函数添加工程libs目录下的Native库(注意:NDK编译生成so或bin文件),最后调用sealApk()关闭apk文件。
6、对apk进行签名。签名后才能在andriod设备上使用,签名apk有两种:
1) 是在调试程序时进行签名,使用Android-studio进行生成。
2) 打包发布时对程序进行签名。
而签名的方法也有两种:
1) 使用jdk中提供jarsigner工具签名
2) 使用andriod源码中提供的signapk工具,它的代码是位于
/android-4.0.3_r1/build/tools/signapk
7、对签名后的APK文件进行对齐处理。这一步需要使用到的工具为zipalign,它位于
/root/android-sdk/tools目录,对应的andriod源码为如下:
/root/android-4.0.3_r1/build/tools/zipalign
主要的工作是将apk包进行对齐处理,使apk包中的所有资源文件距离文件起始偏移为4位字节整数倍,这样通过内存映射访问apk文件时的速度会更快