APK的结构


昨天说到,今天来讲一讲APK的结构。今天上火依旧时间很紧张,在抽空把后台传输进度条和文件上传、压缩解决了一下后,就时间不多了,但说到的还是要做,今天就先简单谈一谈APK的结构吧。

一、APK包主要结构

首先,安卓程序安装包(后缀.apk)的实质其实就是一个压缩包把安装包的后缀.apk改为.zip,然后就可以直接解压,在这一步根本用不上什么所谓的反编译工具。反编译工具实际是用于反编译apk压缩包中的JAVA的源码,供开发者测试自己非开源程序源码被盗取难度之用的。
我们重命名apk后缀为.zip后,可以看到APK中包含3到4个目录和3个文件,它们分别是:
  1. assets目录
  2. lib目录(可能不存在)
  3. res目录
  4. META-INF目录
  5. AndroidManifest.xml
  6. classes.dex
  7. resources.arsc
这里的第一个目录是用来存放要打包到APK的静态资源,如一些程序使用过程中涉及的图片、网页,以及3D游戏中使用的模型等。
2号目录是存放程序依赖库的,比如以后后谈到的用C或CPP语言开发安卓程序,这里C或CPP语言开发的实际就是程序的核心库,然后用JAVA做简单包装,这时的程序核心库就主要存放在这个目录。根据CPU型号不同,需要对不同架构CPU分别编译依赖库,存放在对应CPU型号子目录中。
3号目录是存放应用程序资源的,比如安装这个软件后的手机桌面的图标等等就放在这里面其中anim存放动画文件;drawable目录存放图像资源,layout目录存放布局文件,values目录存放一些特征值的XML。
4号目录我们待会详细介绍。
5号文件是应用程序的配置文件,描述安卓应用的整体信息,相当于给系统的自我介绍,只有在这介绍的内容,才便于系统为程序启用对应组件。
6号是可执行文件,即使你用C语言开发这个安卓软件,也需要JAVA的可执行文件包装一下,才能运行
7号文件是资源的配置文件,用来记录资源文件和资源ID的映射关系。

这里1号目录和3号目录不同的是1号目录的目录层数任意,3号目录的文件都要有对应ID在安卓工程的.R文件中,而1号不会自动产生对应ID,需要AssetManager类来访问。

二、APK包安装过程

安装APK时,首先把APK复制到/data/app目录,然后校验签名,检查APK结构是否正常,校验dex文件,确定没损坏后,优化为odex,存放到/data/dalvik-cache目录在/data/data目录以apk包名建立文件夹如果apk有lib库那么判断lib库格式正常后将对应CPU架构的so文件(lib库)解压/data/data/packagename/lib目录。

三、APK签名文件

在APK的META-INF目录中,有三个文件:MANIFEST.MFCERT.SFCERT.RSA。
MANIFEST.MF是摘要,遍历APK包里所有文件,对除了文件夹与签名文件以外的所有文件逐个用SHA1算法生成摘要信息,然后用Base64进行编码为可见字符串。如果你改变了APK中某个文件,那么那个文件对应的这里的记录必须对应,否则程序就无法正确安装
CERT.SF是对之前摘要的签名文件,把之前摘要文件用SHA1算法,用Base64进行编码,然后把之前摘要的内容每条也分别用SHA1算法,用Base64进行编码。如果之前摘要改了,那么这一步也要对应修改,否则就无法对应。
CERT.RSA保存了非对称加密算法用到的公银,和用到的加密算法信息,以及对CERT.SF内容进行私银加密后的值。这样即使他人修改了程序内容,并完成前两步生成摘要,因为这里非对称加密后,根据公银只能解密验证,所以系统验证程序时验证无法通过,也就不能成功安装文件
以上3个文件环环相扣,就是为了防止开发者开发的程序被攻击者修改,只要开发者保护好非对称加密的私银,攻击者就不便对程序进行更改。
通常来说,同一个厂商开发的不同程序的公钥与签名都不尽相同(顶多签名中有部分相同字段),但同一个软件不同版本公钥与签名在非特殊情况下都是相同的。
CERT.SFCERT.RSA两个文件名被修改为为其它名字,只要两个文件名部分相同,通常APK都还是能正常安装。另外我们添加自己的CERT.SFCERT.RSA会出现对应问题。