Android可执行程序的生成步骤

 Stardustsky   2015-11-02 23:04   1519 人阅读  0 条评论

    最近一直在学习Android安全相关的东西,也渐渐摸到了门路,这几天在啃非虫的《Android软件安全与逆向分析》,第四章提到了Android程序的生成步骤,觉得挺不错的,手敲下来记录着。

    Google提供了Android SDK供程序员来开发Android平台的软件。每个软件在最终发布时会打包成一个APK文件,将APK文件传送到Android设备中即可安装。而实际上apk文件就是一个zip压缩包,解压后会发现一些图片资源文件与其他文件组成,并且在每个apk文件中包含一个class.dex,这个class.dex就是Android系统Dalvik虚拟机的可执行文件。

    Android工程打包有两种方式:一种是使用Eclipse集成开发环境直接导出生成apk;另一种是使用ant工具在命令行下打包生成apk。apk的打包编译过程由七个步骤完成:

    第一步:
        打包资源文件,生成R.java文件。打包资源工具aapt位于Android-sdk\platform-tools目录下,该工具的源码在Android系统源码的frameworks\base\tools\aapt目录下,生成过程主要是调用了aapt源码目录下Resource.cpp文件中的buildResource()函数,该函数首先检查AndroidManifest.xml的合法性。然后对res目录下的资源子目录进行处理,处理的函数为makeFileResource(),处理的内容包括资源文件名的合法性检查,向资源表table添加条目等。处理完后调用compileResourceFile()函数编译res与assert目录下的资源并生成resources.arsc文件,compileResourceFile()函数位于aapt源码目录的ResourceTable.cpp文件中,该函数最后会调用parseAndAddEntry()函数生成R.java文件。完成资源编译后,接下来调用compileXmlFile()函数对res目录的子目录下的xml文件分别进行编译,这样处理过的xml文件就简单的被“加密了”,最后将所有的资源与编译生成的Resource.arsc文件以及“加密”过的AndroidManifest.xml文件打包压缩成Resource.ap_文件(使用ant工具命令行编译则会生成与build.xml中“project name”指定的属性同名的ap_文件)。

    第二步:
        处理aidl文件,生成相应的java文件。对于没有使用到aidl的Android工程,这一步可以跳过。这一步使用到的工具为aidl,位于android-sdk\platform-tools目录下,aidl工具解析接口定义文件并生成相应的java代码供程序调用,它的源码位于Android源码的frameworks\base\tools\aidl目录下。

    第三步:
        编译工程源代码,生成相应的class文件。这一步调用javac编译工具src目录下所有的java源文件,生成的class文件位于工程的bin\classes目录下,在实际开发过程中,也有可能会使用Android NDK来编译native代码,因此,如果可能的话,这一步还需要使用Android NDK来编译native代码,当然,编译C++/C代码的步骤也可以提前到第一步或第二部。

    第四步:
        转换所有的class文件。生成classes.dex文件。前面提到,Android系统Dalvik虚拟机的可执行文件为dex格式,程序运行所需的classes.dex就是在这一步生成的。使用到的工具为dx,位于android-sdk\platform-tools目录下,dx工具的主要工作是将java字节码转化为Dalvik字节码,压缩常量池,消除冗余信息。

    第五步:
        打包生成apk文件。打包的工具为apkbuilder,它位于android-sdk\tools目录下,apkbuilder为一个脚本文件,实际调用的是android-sdk\tools\lib\sdklib.jar文件中的com.android .sdklib.build ApkBuilderMain类。它的实现代码位于Android系统源码的sdk\sdkmanager\ libs\sdklib\src\com\android\sdklib\build\ApkBuilderMain.java文件,代码构建了一个ApkBuilder类,然后以包含Resource.arsc的文件为基础生成apk文件,这个文件一般会调用processFileForResource()函数往apk中添加资源,处理的内容包括res目录与assert目录中的文件,添加完资源后调用addResourceFormJar()函数往apk文件中写入依赖库,接着调用addNativeLibraries()函数添加工程libs目录下的native库(通过NDK编译生成的so或bin文件),最后调用sealApk()关闭apk文件。

    第六步:
        对apk文件进行签名,Android应用程序需要签名才能在android设备上安装,签名apk文件有两种情况:一种是在调试程序时进行签名,使用eclipse开发android程序时,在编译调试程序时会自己使用一个dubug.keystore对apk进行签名;另一种是打包发布时对程序进行签名,这种情况下需要提供一个符合android开发文件当中要求的签名文件。签名的方法也有两种:一种是使用JDk中提供的jarsigner工具签名;另一种是使用Android源码中提供的signapk工具,它的代码位于Android系统源码的build\tools\signapk目录下。

    第七步:
        对签名后的APK文件进行对齐处理。这一步需要使用到的工具为zipalign,它位于Android-sdk\tools目录下,源码位于Android系统源码的build\tools\zipalign目录,它的主要工作是将apk包进行对齐处理,使apk包中的所有资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快,验证apk文件是否对齐过的工作由ZipAlign.cpp文件的verify()函数完成,处理对其的工作则由process()函数完成。


20140819102054109.jpg

本文地址:http://www.stardustsky.net/index.php/post/32.html
版权声明:本文为原创文章,版权归 Stardustsky 所有,欢迎分享本文,转载请保留出处!

 发表评论


表情

还没有留言,还不快点抢沙发?