这里简单介绍一下我认识的apk。对于apk 的理解其实也是逆向的基础内容,对于apk的理解和熟悉程度能直接影响我们对逆向过程的理解,也能给我们逆向过程提供更开阔是思路。
主要包括三个内容:
一、apk的包结构
二、apk的打包过程
三、apk的安装过程
四、apk加载/(启动运行)过程
先来看看apk的包结构:
其实我们的apk 也好,jar 也好,其实都是可以看做是一个zip压缩包的。不信的可以自己使用zip工具浏览下压缩包结构。
我们这里随便找一款apk,然后解压开。就可以看到类似以下的结构:
其中各个文件夹存放的内容如下:
assets 资源文件(图片、音频、数据库、网页、配置文件等)
res 资源文件,需要编译(布局layout),还有一些drawable, menu,之类的文件
libs 存放一些第三方的jar包,这个跟一般的java代码类似
META-INF
存放文件摘要,摘要加密和签名证书等,可以看到对apk中所有的资源都进行了一次hash运算,为了防止apk的文件被修改,如果其中的文件别修改就能被检测出来,很多apk都会做这个校验,以保证apk的安全
META-INF/CERT.RSA 公钥以及加密算法的描述
META-INF/CERT.SF
加密文件,它是使用私钥对摘要明文加密后得到的密文信息,只有只用私钥匹配的公钥才能正确解开密文
META-INF/MANIFEST.MF
程序清单文件,包含包中所有文件的摘要明文
resources.arsc 资源文件,经过aapt工具加密的(语言包)
AndroidManifest.xml 清单文件(图标、界面、权限、入口)
classes.dex
源代码,这是dalvik虚拟机运行的,其实其实就是smali代码。我们可以用一些工具将它转为jar,java之类的。也就是我们的源码。很多大的apk,我们加压之后都会看到好几个dex文件,这是因为我们每一个dex的文件大小都是有限制的。其实在真正运行的时候,是需要将这些dex都整合起来的。而且一般情况下,这些dex是不会重复的。
lib 各种平台下使用的对应的so文件,继续打开可以看到:
其实不同的apk可能还会有更多别的文件夹。这就意味着这个apk支持更多的CPU平台。对于我们的语言,最底层是机器码,然后是汇编代码,C语言这样的高级语言。但是对于汇编和机器码来说,这些代码是需要具体机器支持的。即是不同的cpu有自己的一套汇编指令,所以我们如果要兼容不同的cpu,就需要程序提供不同机器上运行的汇编代码。这里的每一个文件夹就是对一个cpu平台做兼容
这里的armeabi 就是存放的 arm 5 平台下运行的,armeabi-v7a 存放的就是arm 7 平台下运行的。当然我们可能会遇到更多的比如arm 8 (64位cpu)下的,x86下的等等。
其实这里面的代码可能有兼容的。比如armeabi-v7a是可以兼容armeabi,也就是说你将v7a 下的so文件移动到 armeabi 下,一般也是没有问题的。但是这里有一点需要注意的,涉及到我们的动态调试。就是我们需要注意下自己的调试机子上的cpu 架构,才能正确找得到自己真实运行的so文件。不然很可能遇到自己机子上真正运行的so平台,跟实际上静态分析上的so不同的情况
接下来是介绍下apk 的打包过程,大致的流程图如下:
根据上图大致可以分为几个步骤
1、打包资源文件。
使用aapt来打包res资源文件,包括assert 、res、AndroidManifest.xml等文件。最后生成R.java和resources.arsc 文件
2、处理AIDL文件
这个不一定有,但是如果app中涉及到跨进程通信的话大多会出现,我们需要将AIDL文件转为java文件。
3、编译生成.class 代码。
项目中的java源码,aidl转化的java代码等全部编译成.class
4、将所有的.class 转为dex文件
android中并不直接执行.class。而是使用的dalvik虚拟机,所以需要将clasa转为dex。这里的class除了有我们的源码,也可能来自于第三方提供的jar。我们需要将所有的.class 都打包成dex。这里需要注意下dex的大小是有限制的,所以可能生成多个dex。
5、打包生成apk文件
通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk。打包的工具apkbuilder位于 android-sdk/tools目录下。
6、对apk文件进行签名
只有经过签名的apk才允许被安装,我们开发中能用debug版本安装其实也是开发环境帮我们用自带的debug签名了我们的apk。
7、对签名后的APK文件进行对齐处理
通过zipalign工具,将签名后的apk进行对齐处理。工具位于android-sdk/tools目录下。对齐的主要过程是将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。对齐的作用就是减少运行时内存的使用。
经过这样的步骤,一个apk 就大致诞生了。
apk生成之后就到apk的安装了,我们来看看一个apk是如何被安装上的。