APK本质是ZIP文件,可用zlib等库解压;AndroidManifest.xml为二进制AXML格式,magic number为0x03000800,不可直接当文本读取。

APK本质是ZIP,用标准库解压就行
APK 文件没有加密或特殊封装,就是个符合 ZIP 格式规范的归档文件。C++ 本身不内置 ZIP 解压能力,但你可以直接调用 zlib 或更易用的第三方库(如 miniz、libzip)来读取。Android 构建工具(aapt2)生成的 APK 也遵循 ZIP 的 central directory 结构,只要没被签名块(APK Signing Block)干扰,常规 ZIP 解析器就能定位到 classes.dex、AndroidManifest.xml 等文件。
AndroidManifest.xml 是二进制 XML,不能直接当文本读
你用 fopen 或 std::ifstream 读出的 AndroidManifest.xml 内容是 AXML 格式——即 Android 特有的二进制 XML,头部有 magic number 0x03000800。直接 std::cout 会看到乱码甚至崩溃(因含 null 字节)。必须先解析 AXML 结构,提取字符串池、元素标签、属性表等。
- 推荐用开源库
axmlparser(轻量,头文件仅axml.h)或android-xml-parser - 不要尝试用 libxml2 / tinyxml2 直接加载,它们只认文本 XML
- 若只需提取包名/权限/启动 Activity,可跳过完整解析,用
axmlparser的get_package_name()等辅助函数
读取 classes.dex 要注意 DEX 文件格式边界
classes.dex 是 Dalvik 可执行格式,开头固定是 "dex\n035<p><code>classes.dex 是 Dalvik 可执行格式,开头固定是 "dex\n035\0"(8 字节 magic)。C++ 读取后不能直接执行或反编译,但可做基础校验:
YZTurboWebAndroid 高性能 Android WebView 容器 SDK 接入。用于在 Android 项目中集成 WebView 容器,实现: (1) WebView 预加载与复用,提升 H5 页面加载速度 (2) 离线包管理,拦截请求优先命中本地资源 (3) JS Bridge 双向通信,Na...
- 检查
header[0..7]是否等于"dex\n035\0"(注意换行符和末尾 null) - 读取
header[0x20]开始的uint32_t file_size,验证是否与 ZIP 中声明的压缩/未压缩大小一致 - 若 APK 含多个 dex(如
classes2.dex),需遍历 ZIP 目录逐个匹配文件名前缀 - NDK 开发中常配合
libdexfile(Android 源码中的libdexfile.so)做进一步解析,但该库非公开 ABI,不建议直接链接
签名块(Signing Block)会破坏 ZIP 遍历逻辑
Android 7.0+ 强制使用 APK Signature Scheme v2/v3,在 ZIP central directory 之前插入一段签名块(由长度 + payload 组成),导致传统 ZIP 库(如 miniz)从文件末尾找 EOCD(End of Central Directory)时可能失败或跳过真实目录。表现是:能列出 META-INF/ 下文件,但找不到 res/ 或 classes.dex。
立即学习“C++免费学习笔记(深入)”;
- 解决方法:先定位并跳过签名块。签名块位于 ZIP 文件末尾前约 23 个字节处,结构为
[8-byte size][payload][8-byte size],两个 size 字段相等且为 payload 长度 - 更稳妥的做法是用
apkanalyzer(Android SDK 工具)或zipinfo -v查看实际 central directory offset,再用std::ifstream::seekg()定位 - 若只是分析自有 APK(已知未启用 v2 签名),可忽略此问题;但处理用户上传 APK 时,必须兼容签名块

















