Apktool ApkInfo 全解:apktool.yml 是怎么被读写并支撑重打包的

发布时间:2026/10/29 2:02:06

Apktool ApkInfo 全解:apktool.yml 是怎么被读写并支撑重打包的 Apktool ApkInfo 全解apktool.yml 是怎么被读写并支撑重打包的【免费下载链接】ApktoolA tool for reverse engineering Android apk files项目地址: https://gitcode.com/GitHub_Trending/ap/Apktool用 Apktool 反编译一个 APK输出目录里会生成apktool.yml重新打包时又靠这个文件决定怎么构建。可这些字段到底是谁写进去的、构建时又是谁在消费答案是 meta 包下的 ApkInfo 类——Apktool 中 APK 元数据的唯一载体贯穿解码与重打包两个阶段。整体架构一个对象、一套自研 YAML、两个消费方ApkInfo 处在两个环节的交接点上数据链长这样APK ── ApkDecoder解码── ApkInfo 对象 ──save()── apktool.yml apktool.yml ──ApkInfo.load()── ApkInfo 对象 ── ApkBuilder重打包拆开看是三层元数据层ApkInfo 及 meta 包下的五个子对象UsesFramework、SdkInfo、VersionInfo、ResourcesInfo外加 usesLibrary 与 doNotCompress 两个列表序列化层brut.j.yaml 模块里自研的 YamlReader/YamlWriter不依赖第三方 YAML 库逐行解析消费方ApkDecoder 负责填充并落盘ApkBuilder 负责读回并消费简单说apktool.yml是解码与重打包之间唯一的交接契约ApkInfo 是这份契约唯一的翻译器。核心流程从解码到重打包走一遍解码侧ApkDecoder 边解边填最后落盘在 ApkDecoder 里能看到完整的写入链路mApkInfo new ApkInfo(); mApkInfo.setVersion(mConfig.getVersion()); mApkInfo.setApkFile(mApkFile); mResDecoder new ResDecoder(mApkInfo, mConfig); // ... 资源、Manifest 解码完成后 ... mApkInfo.save(outDir);关注最后一行save() 就是打开输出目录下的固定文件名apktool.yml调用 write()。SDK 版本、版本号、资源包 ID 这些字段并非都直接由 ApkDecoder 填而是解码资源与 Manifest 的阶段回写进同一个对象featureFlags、doNotCompress 条目也是这一过程陆续追加的。重打包侧ApkBuilder 读回来立刻用ApkBuilder 的第一步正好是上面链路的反向操作mApkInfo ApkInfo.load(mApkDir); String minSdkVersion mApkInfo.getSdkInfo().getMinSdkVersion(); mSmaliBuilder new SmaliBuilder(minSdkVersion ! null ? SdkInfo.parseSdkInt(minSdkVersion) : 0); mAaptInvoker new AaptInvoker(mApkInfo, mConfig);关键在第二行起minSdkVersion 决定 smali 汇编的输出等级AaptInvoker 则拿 apkInfo 里的框架与资源信息决定怎么编译资源。而apktool.yml一旦缺失load() 会抛 IOException 并被包装成 AndrolibException——这就是没有 apktool.yml 就构建不了的直接原因。序列化层逐行解析而不是 YAML 库YamlReader 在构造时把输入流切成一行行 YamlLine每行只记四个属性indent空格数、hasColon、isItem-开头、isComment。readRoot 只处理缩进为 0 且带冒号的行再分发给 readItem()sdkInfo 这类嵌套对象由 readObject 读取要求数据行缩进严格大于键行。这个设计带来一个直接后果无法识别的行——未知字段、缩进不符——会被静默跳过而不是报错。apktool.yml 里每个字段到底存了什么看仓库测试资源里的真实样例testapp/apktool.yml 前段version: 2.3.2 apkFileName: testapp.apk usesFramework: ids: - 1 versionInfo: versionCode: 1 versionName: 1.0 resourcesInfo: packageId: 127 sparseEntries: false # ... 其余字段省略 ... doNotCompress: - arsc - png各字段与 ApkInfo 的成员变量一一对应几个容易忽略的点空字段干脆不写write() 里每个字段都有非空判断所以某个文件里看不到 sdkInfo 属正常现象-1 与 nullversionCode 为 -1、versionName 为 null 表示原 Manifest 没声明版本YamlWriter 会把 null 写成字符串null读回时再还原packageId 通常为 1270x7fAPK 里的资源引用都依赖这个值改动它会导致引用错位sdkInfo 存的是字符串parseSdkInt 还认识 O、TIRAMISU 这类发布名别名getTargetSdkVersionBounded() 会把 target 钳到 [min, max] 区间内apkFileName 有加载校验值为./..或含路径分隔符会直接抛 SecurityException这是对 CVE-2022-0476 的防御典型用法查框架、批量改元数据、控压缩如果你要快速确认 APK 依赖的框架看usesFramework.ids1 是默认 Android 框架tag 有值时指向自定义框架标签如果你要在脚本里批量改元数据load → 修改 SdkInfo/VersionInfo → save() 即可仓库里的 ApkInfoSerializationTest 做的就是这种 load → save → 再 load 的往返断言可当模板参考如果你要控制重打包时的文件压缩doNotCompress 决定哪些文件在新 APK 中以未压缩方式存放解码器会自动往这里记录 0 字节文件和不常规扩展名的文件别手删条目常见坑缩进丢数据、SecurityException、解析异常缩进错误不报错只丢数据。现象改了 apktool.yml构建行为却像没改。原因readRoot 会静默跳过缩进不符或没有冒号的行未知字段同样被忽略。解法手工改完后用 ApkInfo.load() 读回并断言关键字段ApkInfoReaderTest 的 testSkipIncorrectIndent 就是这么验证的。apkFileName 写成路径直接 SecurityException。现象抛 Malicious value for apkFileName 而非解析错误。原因加载时校验拒绝./..及含/、\的值。解法该字段只记 APK 原始文件名别带路径。sdkInfo 手写真数导致解析异常。现象构建失败NumberFormatException。原因值按字符串读入parseSdkInt 先试发布名别名、回退 Integer.parseInt对任意写法并不宽容。解法写数字如 25或合法别名如 TIRAMISU。删掉 apktool.yml重打包立刻失败。现象apktool b报 FileNotFoundException。原因ApkBuilder 第一步就是 ApkInfo.load(mApkDir)它是构建参数的唯一来源。解法把它当作反编译目录的一部分提交进版本库。apktool.yml是解码与重打包两个阶段之间的交接契约ApkInfo 是这份契约唯一的翻译器。看懂这个文件构建为什么长这样就不再是黑盒。【免费下载链接】ApktoolA tool for reverse engineering Android apk files项目地址: https://gitcode.com/GitHub_Trending/ap/Apktool创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/29 2:01:24

Svelte style: 指令完全指南:从模板语法到编译与运行时实现

Svelte style: 指令完全指南:从模板语法到编译与运行时实现 【免费下载链接】svelte web development for the rest of us 项目地址: https://gitcode.com/GitHub_Trending/sv/svelte 本篇基于 Svelte 官方文档中的 style: 指令说明,系统讲解这一…

2026/10/25 7:50:11

蓝牙音箱系统设计实战:从模块划分到整机验证

蓝牙音箱是消费电子里少有的“四合一”项目:射频、音频、电源、声学,任何一个方向单独拿出来都能养一个工程师岗位,但在这类产品里,所有人必须围绕同一个腔体和同一块 PCB 协作。这也是为什么很多蓝牙音箱项目开案时各模块都正常&…

2026/10/25 7:50:19

AGENTS.md 使用教程:三步让 AI 编程代理读懂你的项目

AGENTS.md 使用教程:三步让 AI 编程代理读懂你的项目 【免费下载链接】agents.md AGENTS.md — a simple, open format for guiding coding agents 项目地址: https://gitcode.com/GitHub_Trending/ag/agents.md AGENTS.md 是一个开放、无门槛的标准文件格式…

2026/10/29 1:58:50

Folia 完整安装部署指南:从零跑通全屏歌词动画

Folia 完整安装部署指南:从零跑通全屏歌词动画 【免费下载链接】folia-major 专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器 项目地址: https://gitcode.com/GitHub_Trending/fo/folia-major Folia 全屏歌词动画播放器&#xff…

2026/10/29 1:58:50

华为智慧化工园区解决方案

这份华为智慧化工园区解决方案 PPT 结合国家化工园区安全环保相关政策,剖析园区信息化建设分散、风险管控薄弱、数据难以共享等现实痛点,梳理安监、环保、应急、物流、安防、能效等核心业务场景,依托 IoT、GIS、AI、大数据等技术搭建数字化使…

2026/10/29 1:53:49

【FDE系列】阶段2:Day 46:RESTful 设计与认证授权

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/29 0:03:42

学生选课系统DFD图绘制指南:边界划分与分层校验实战

简介:文档以顶层与第一层DFD图为核心,完整刻画学生选课系统的逻辑模型,面向软件工程课程设计、系统分析学习及毕设前期建模人群。顶层图界定系统边界,外部实体包括管理员、教师和学生三类角色;第一层图进一步细化用户登…

2026/10/29 0:03:42

JIRA敏捷落地:Scrum角色权限、Sprint与燃尽图避坑指南

简介:围绕“基于JIRA的敏捷开发项目管理”这一主题,面向产品负责人、Scrum Master及研发测试成员,梳理Scrum角色分工、迭代流程与JIRA工具配置的对应关系,适合初、中级团队导入敏捷管理时参考。压缩包共1个docx文件,大…

2026/10/29 0:03:42

SEMI S8人机工程验收实战:从条款拆解到现场实测的完整指南

简介:面向半导体设备设计、制造与运维工程师及安全合规人员,这份资料聚焦SEMI标准体系下的设备安全规范,重点收录SEMI S8-0308《半导体制造设备人体工程学工程安全指南》。内容围绕设备设计原则、错误与事故预防、人体工程学适配三大主线展开…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑