ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

拆解 Apktool 的 APK 元数据:如何看懂 apktool.yml 并一次性完成重打包

拆解 Apktool 的 APK 元数据:如何看懂 apktool.yml 并一次性完成重打包 拆解 Apktool 的 APK 元数据如何看懂 apktool.yml 并一次性完成重打包【免费下载链接】ApktoolA tool for reverse engineering Android apk files项目地址: https://gitcode.com/GitHub_Trending/ap/Apktool跑apktool d test.apk后反编译目录顶部会多出个apktool.yml。看不懂它重打包时就会莫名踩坑。这篇文章带你走通「反编译 → 读懂 APK 元数据 → 改一处 → 重新打包」的完整闭环主线就是核心类 ApkInfo。先搞清楚apktool.yml 为什么非落盘不可元数据不是「顺便存一下」而是重打包的直接输入。整条数据流是这样的反编译 (apktool d) → ApkDecoder 从 AndroidManifest.xml / resources.arsc 提取元数据 → 塞进内存里的 ApkInfo 对象 → mApkInfo.save(outDir) 落盘为 apktool.yml ↓ 你在这一步修改 smali / res / apktool.yml 重打包 (apktool b) → ApkBuilder.build 第一件事ApkInfo.load(mApkDir) 回读 → minSdkVersion 决定 smali 组装的字节码级别 → doNotCompress 决定 zip 里哪些文件必须存为 uncompressed → 产出 dist/*.apk拆开看重打包时哪些环节真的在读这些值minSdkVersionApkBuilder.build里直接new SmaliBuilder(parseSdkInt(minSdk))smali 反汇编成 dex 时用哪个 API 级别由它说了算。doNotCompress最终 zip 打包时作为压缩白名单传入名单外的文件一律压缩存储。usesFramework交给AaptInvoker决定 aapt 重建资源表时链接哪个系统框架。apkFileName决定dist/下输出 APK 的文件名。也就是说反编译后的目录里只有 smali、res 这些「零件」而「怎么装回去」的说明书只有这一份。这就是它必须存在的原因。如何读懂 apktool.yml一张表讲完关键字段一份典型配置长这样键名均来自 ApkInfo 源码 的解析逻辑version: 2.9.0 apkFileName: test.apk usesFramework: ids: - 1 sdkInfo: minSdkVersion: 25 targetSdkVersion: 30 versionInfo: versionCode: 1024 versionName: 1.2.4 resourcesInfo: packageId: 127 packageName: com.example.test doNotCompress: - arscyaml 键通俗含义乱改的风险version生成该目录的 Apktool 版本号影响小主要留痕打包实际用本机版本apkFileName原始 APK 文件名决定dist/输出名名字错了不致命只是产物名不对含/、..的值在读取时会被直接以SecurityException拒绝usesFramework(ids/tag)依赖的 Android 框架。ids: [1]就是标准 Android 框架系统应用往往依赖更多填了不存在的框架 id构建期直接找不到框架而失败usesLibrary清单里声明的第三方库uses-library列表一般不用动动了会偏离原始声明sdkInfo(min/target/max)应用支持的 SDK 下限 / 目标 / 上限见下方「坑」小节target 会被夹在 [min, max] 区间内生效三者关系乱了会出兼容问题versionInfo(versionCode/versionName)应用版本号与版本名versionCode 不升反降渠道侧会拒绝「降级」resourcesInfo(packageId/packageName/sparseEntries/compactEntries/keepRawValues)资源包 ID、包名与资源表存储格式高危。packageId改一位所有0x7f…资源引用的高位前缀全部失效featureFlags功能开关表键值对影响资源行为细节不确定就别动doNotCompress必须以不压缩形式进 zip 的后缀/文件名清单把arsc这类条目删掉resources.arsc被压缩存储系统无法按原方式读取一个容易忽略的细节write()方法对每个块做了isEmpty()判断空块直接不写。所以你在apktool.yml里看到的内容就是这个 APK「实际携带」的全部元数据没出现的键就是没有。对比三条读写路径目录、输入流、回写ApkInfo的持久化只围绕apktool.yml这一个文件名入口有三个方式关键 API适用场景从目录读ApkInfo.load(File apkDir)真实构建流程的唯一入口。ApkBuilder.build第一行就是它内部定位到apkDir/apktool.yml读不到抛AndrolibException从流读static ApkInfo load(InputStream in)包私有 VisibleForTesting。用YamlReader直接解析流不碰文件系统适合写测试或纯内存校验脚本回写apkInfo.save(File apkDir)反编译收尾时由ApkDecoder调用把内存对象序列化成 yaml 落盘如果你要程序化改元数据套路就是「load → setter → save」ApkInfo info ApkInfo.load(decodedDir); info.getSdkInfo().setTargetSdkVersion(28); info.getVersionInfo().setVersionCode(2048); info.save(decodedDir);所有 getter/setter 都是公开的SdkInfo、VersionInfo、ResourcesInfo、UsesFramework这几个 元数据组件 也都提供同类访问器想改哪块改哪块。避坑四个高频踩点坑 1apktool.yml 被删、被截断、缩进被改坏为什么踩load是逐行解析的文件缺失抛 IO 异常缩进错乱直接解析失败构建在第一步就死。正确做法把它当源码一样放进版本管理手工编辑只用能保持缩进的编辑器真损坏了拿原始 apk 重新d一遍比重修文件省事。解析与容错的边界行为可以参考 meta 测试目录 里的用例。坑 2随手改resourcesInfo.packageId为什么踩资源引用 ID 的高位字节就是包 ID0x7f对应 127。改了 ID 而不动引用或引用与新 ID 不匹配资源表构建完也无法互相对上。正确做法没有明确需求就别碰真要改必须保证 aapt 重建出的资源表与引用方一致并在真机上验证资源解析。坑 3SDK 三段值改乱为什么踩minSdkVersion直接决定 smali 组装的字节码级别targetSdkVersion生效前会被SdkInfo.getTargetSdkVersionBounded()夹进[min, max]区间。比如你把 target 提到 34 但 max 只有 30实际生效的是 30你以为改了却没改。正确做法保持min ≤ target ≤ max小步调整改完跑一次 build看日志里是否有 target 低于某阈值导致的警告源码里对网络配置等场景就有这类提示。坑 4给usesFramework.ids加不存在的框架为什么踩id 指向系统里实际安装的框架 APK不是随便编的序号。正确做法普通应用保留[1]只有系统应用需要额外框架时才加并确保构建机上已用apktool if安装对应框架否则会直接报框架找不到。进阶把元数据接进批量处理和 CI这套机制对自动化是友好的两个现成玩法批量改版本再打包循环遍历反编译目录对每个目录执行ApkInfo.load(dir)→ 按规则setVersionCode/setVersionName→save(dir)→ 调apktool b。因为所有访问器都是公开的不需要动任何 apktool 内部实现。CI 前置校验利用流式入口写一个不落地文件的检查器——读取apktool.yml流断言sdkInfo三值非空且有序、resourcesInfo.packageId在预期集合内、usesFramework.ids非空、apkFileName不含路径分隔符这条恰好是源码内置的防御。把它挂在 CI 里反编译产物一进仓库就先过校验坏数据不用等到打包才暴露。测试写法可以直接对照 ApkInfoReaderTest 这类现成用例。收尾一句话记住apktool.yml是反编译留给重打包的交接单ApkInfo.load回读的那一刻起minSdk、框架依赖、压缩策略全部由它说了算。动手前先把apktool.yml备份一份改完跑一次apktool b把日志里 SDK 和框架相关的警告当第一审查点 ️【免费下载链接】ApktoolA tool for reverse engineering Android apk files项目地址: https://gitcode.com/GitHub_Trending/ap/Apktool创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表