APK 文件结构详解
APK 文件结构详解
APK (Android Package) 是 Android 操作系统用于分发和安装移动应用的文件格式。它本质上是一个 ZIP 归档文件,包含了应用的所有代码、资源、证书等。理解其内部结构是逆向工程和安全分析的第一步。
APK 概览
一个标准的 APK 文件,当用解压缩工具打开时,通常会看到以下目录结构:
| |
AndroidManifest.xml
这是 APK 中最重要的文件,它以二进制 XML 格式存储,包含了应用的所有元信息。
核心内容
| 元素 | 说明 |
|---|---|
| 包名 (Package Name) | 应用在系统中的唯一标识符,如 com.example.app |
| 组件 (Components) | 声明所有四大组件:Activity、Service、BroadcastReceiver、ContentProvider |
| 权限 (Permissions) | 声明应用需要申请的权限,如 android.permission.INTERNET |
| 入口点 (Entry Point) | 指定哪个 Activity 是应用的启动入口(LAUNCHER Activity) |
| SDK 版本 | 指定 minSdkVersion、targetSdkVersion |
四大组件
| |
分析提示: 必须使用 apktool 或 jadx 等工具将其解码为人类可读的 XML 格式。直接用文本编辑器打开是乱码。
classes.dex
这是由 Java/Kotlin 代码编译、转换后生成的 Dalvik 虚拟机字节码。应用的所有业务逻辑都在这里。
DEX 文件特点
| 特性 | 说明 |
|---|---|
| 格式 | Dalvik Executable,专为移动设备优化 |
| 方法数限制 | 单个 DEX 文件最多 65536 个方法 |
| 多 DEX | 超过限制时会有 classes2.dex, classes3.dex 等 |
| 字节码 | 基于寄存器的指令集,比 JVM 字节码更紧凑 |
分析工具
| |
分析提示: 使用 jadx 可以将其反编译为 Java 代码,使用 baksmali 可以反汇编为 Smali 代码。
resources.arsc
这是一个二进制资源索引表。Android 系统使用它来快速查找和匹配资源。
功能说明
- 包含从资源 ID 到具体资源文件(或字符串值)的映射关系
- 支持多语言、多屏幕密度等资源适配
- 当代码中调用
R.string.app_name时,系统通过此文件找到对应的字符串值
资源 ID 格式
| |
分析提示: apktool 可以解码此文件,将其中的字符串等资源还原到 res/values/strings.xml 等文件中。
res/ 目录
存放未编译的资源文件,这些资源在打包时大多保持原样或只进行简单处理。
目录结构
| 目录 | 内容 |
|---|---|
res/drawable/ | 图片资源(PNG, JPG, WebP, XML drawable) |
res/layout/ | 布局 XML 文件 |
res/values/ | 字符串、颜色、尺寸等值资源 |
res/xml/ | 任意 XML 配置文件 |
res/raw/ | 任意原始二进制文件 |
res/mipmap/ | 应用图标资源 |
res/anim/ | 动画定义文件 |
资源限定符
| |
分析提示: 布局 XML 文件虽然可读,但它们引用的字符串等资源是以 @string/app_name 的形式存在的,需要结合 resources.arsc 才能完全理解。
lib/ 目录
存放应用使用的 C/C++ 原生库(.so 文件)。为了适配不同的 CPU 架构,它通常包含多个子目录。
架构说明
| 目录 | 架构 | 说明 |
|---|---|---|
arm64-v8a/ | 64位 ARM | 目前主流 Android 设备 |
armeabi-v7a/ | 32位 ARM | 较老的 ARM 设备 |
x86_64/ | 64位 x86 | 模拟器、Intel 设备 |
x86/ | 32位 x86 | 模拟器、Intel 设备 |
常见原生库
| |
分析提示: 核心的加密、解密、核心算法或游戏引擎常常在这里实现。需要使用 IDA Pro、Ghidra、Binary Ninja 等工具进行逆向分析。
assets/ 目录
这是一个"原封不动"的资源目录。与 res/raw 类似,这里的任何文件在打包时都不会被系统处理。
常见用途
| 类型 | 示例 |
|---|---|
| 配置文件 | config.json, settings.xml |
| Web 资源 | index.html, app.js, style.css |
| 游戏资源 | 地图数据、关卡配置、精灵图 |
| 字体文件 | custom_font.ttf |
| 数据库 | 预置的 SQLite 数据库 |
| 加密数据 | 加密的配置或密钥文件 |
分析提示: 检查此目录是否有敏感的配置文件、密钥或 Web 资源。
META-INF/ 目录
存放应用的签名信息,用于验证 APK 的完整性和来源。
文件说明
| 文件 | 说明 |
|---|---|
MANIFEST.MF | 包含 APK 中每个文件的名称及其 SHA-256 哈希值 |
CERT.SF | APK 中每个文件的摘要(哈希值) |
CERT.RSA | 包含用于签署 CERT.SF 的公钥和证书 |
签名机制
| |
当系统安装 APK 时,会用 CERT.RSA 中的公钥来验证签名,确保文件自签名后未被篡改。
APK 签名方案
| 版本 | 说明 |
|---|---|
| v1 (JAR 签名) | 传统签名方式,基于 META-INF 目录 |
| v2 (APK 签名块) | Android 7.0+,签名信息存储在 APK 签名块中 |
| v3 (APK 签名块 + 密钥轮换) | Android 9.0+,支持密钥轮换 |
| v4 (增量签名) | Android 11+,支持增量安装 |
分析提示: 对 APK 进行任何修改(包括重打包)后,都必须用自己的密钥重新签名,否则安装会失败。
APK 分析流程
1. 解包
| |
2. 静态分析
| |
检查清单:
- 阅读
AndroidManifest.xml,了解主要组件、权限和入口点 - 检查
assets/目录,寻找配置文件或敏感数据 - 检查
lib/目录,识别使用的原生库 - 搜索硬编码的密钥、URL、API 端点
3. 动态分析
| |
4. 重打包(修改后)
| |
总结
| 文件/目录 | 分析重点 |
|---|---|
| AndroidManifest.xml | 组件、权限、入口点、导出状态 |
| classes.dex | 业务逻辑、加密算法、网络请求 |
| lib/*.so | 核心算法、加密实现、反调试 |
| assets/ | 配置文件、密钥、Web 资源 |
| META-INF/ | 签名信息、证书 |
掌握 APK 文件结构是 Android 逆向工程的基础。通过系统地分析每个组成部分,可以全面了解应用的功能和实现细节。
相关内容
支付宝
微信