Android 应用程序包
Android 应用程序包(Android application package),是 Android 操作系统使用的一种应用程序包文件格式,用于分发和安装移动应用及中间件。APK 文件基于 zip 文件格式,它与 jar 文件的构造方式相似。一个 Android 应用程序的代码想要在 Android 设备上运行,必须先进行编译,然后被打包成为一个被 Android 系统所能识别的文件才可以被运行,而这种能被 Android 系统识别并运行的文件格式便是 APK
APK 结构
一个 APK 文件通常包含以下文件结构:
META-INF目录: 存放应用程序签名和证书的目录lib目录: 程序依赖的Native库res目录: 存放应用程序的资源assets目录: 存放需要打包到 apk 中的静态文件AndroidManifest.xml: Android 清单文件,用于描述该应用程序的名字、版本号、所需权限、注册的服务、链接的其他应用程序classes.dex: classes 文件通过DEX编译后的文件格式,用于在虚拟机上运行的主要代码部分resources.arsc: 资源配置文件

我们来分别介绍一下在这种常见格式下,不同结构中包含的内容
META-INF
META-INF目录里保存应用的签名信息,签名信息可以验证 APK 文件的完整性; Android SDK 在打包 APK 时会计算 APK 包中所有文件的完整性,并且把这些完整性保存到 META-INF 文件夹下,应用程序在安装的时候首先会根据 META-INF 目录校验 APK 的完整性,这样就可以保证 APK 中的每一个文件都不能被篡改, 以此来确保 APK 应用程序不被恶意修改或者病毒感染,有利于确保 Android 应用的完整性和系统的安全性。
META-INF 目录下包含的文件有 CERT.RSA,CERT.DSA,CERT.SF 和 MANIFEST.MF,其中
- CERT.RSA 是开发者利用私钥对 APK 进行签名的签 名文件,
- CERT.SF,MANIFEST.MF 记录了文件中文件的 SHA-1 哈希值
在逆向完成后重新打包的过程中,我们需要对其进行重新签名,会对这里的内容进行修改
lib
lib目录存放应用程序依赖的 native 库文件,一般是用平台原生的语言如C/C++编写,可能包含着一些不同类型的子目录,分别对应着不同的 CPU 架构:
armeabi-v7a和arm64-v8a: ARM v7 和 ARM v8x86/x86_64: x86 平台架构mips: MIPS 架构
平台支持
如果lib目录里没有对应平台的运行库,应用程序还能被正常的安装运行吗? 我们应该如何理解 Native ?