Apktool 参数详解

上一篇 Apktool 使用教程 简单说明了一下 apktool 的基本使用。能够反编译和重新打包一个 apk 了。

如果你学会了使用 -d ,-b 进行 apk 的反编译和重新打包。

那么恭喜你!apktool 你已经学会了 90%的使用了,你也能够反编译绝大多数的 apk 了。

但事情总有小小的例外,有那么一些 apk 它就是不让你如愿。比如加固过的,或者一些厂商的系统应用,它们依赖了一些系统特有的 resource,你不得不进行特殊处理,才能成功的反编译,甚至有时候需要你去修改 apktool 的源码。

所以,这一篇文章就是告诉你那些你平时可能不注意的小细节,不常用的参数到底有什么用。

注意:本文所用 apktool 版本为,2.4.1。

官网介绍:Apktool - Documentation

1、-d 反编译

apktool d bar.apk -o baz

apktool decode bar.apk -o baz

你可以使用-o 来指定反编译的输出目录,如上命令为 反编译 bar.apk 到 baz 目录,也可以使用绝对路径,输出到任意目录。

decode 和 d 以及 -d 等效。

2、-b 打包 apk

apktool b bar -o new_bar.apk

apktool build bar -o new_bar.apk

你可以使用-o 来指定重新打包的输出目录,如上命令为 重新编译 bar 目录下的结构到 new_bar.apk,也可以使用绝对路径,输出到任意目录。

build 和 b 以及 -b 等效。

3、if or install-framework 安装 framework

(1)apktool if framework-res.apk

安装 framework-res.apk 到默认目录,默认目录如下:

  • unix - $HOME/.local/share/apktool

  • windows - %UserProfile%\AppData\Local\apktool

  • mac - $HOME/Library/apktool

(2)apktool if com.htc.resources.apk -t htc

安装 framework-res.apk 到默认目录,并添加 tag 标记,最终可能生成 2-htc.apk,前序的数字,由所安装的 framework 的 pkgId 决定。个人理解 pkgId 是所安装的 framework 的 apk 中的 Manifest 中的 package 字段值。

(3)apktool if framework-res.apk -t baz -p foo/bar

安装 framework-res.apk 到 -p 指定的目录,并添加 tag 标记,最终可能在 foo/bar 目录下生成 2-htc.apk

安装 framework 的作用,是让 apktool 能够识别一些厂商自定义的属性或 resource,否则将反编译失败。

每一个版本的 apktool 都会自带有最新 AOSP 的 framework,能支持绝大多数的 apk 反编译。当需要特殊的 framework 时,如何寻找相应的 framework,请参阅 apktool 文档中的内容,此处不再详述。

如何找到 framework

(4)注意:你需要自己确保默认的 framework 是最新的

apktool 会将自带的 framework 拷贝到默认路径下,各平台默认路径,请参考上文。

但是,当你升级 apktool 之后,最好是去掉默认路径下的 framework,让 apktool 自动安装最新的(自带的)framework。

同时,当默认路径不可用(通常是无权限)时,apktool 会使用 /tmp 目录,但是此目录通常都不稳当,你可以使用 –frame-path(也就是上文提到的 -p ) 指定一个其他的稳定的目录。

从 2.2.1 版本开始,apktool 加入了相应的命令,可以完成此操作。

apktool empty-framework-dir

命令会清除 framework 目录下的所有已安装的 framework

(5)apktool 不会判断 framework 是否重复安装了,你可以任意安装

4、使用指定的 framework 进行反编译

当你安装了不同的 framework,并且其中一些 framework 可能是互不兼容的,那么你在反编译的时候需要指定使用相应的 framework。

安装不同的 framework,并指定 tag

使用指定的 framework 进行反编译,注意查看 log 中的区别。

使用不同的 framework 进行反编译

同时需要说明的是,当你使用了指定的 framework 进行反编译后,想要重新打包 apk 时,不需要再进行 framework 的指定了,apktool 会自动使用反编译时使用的 framework 进行重新打包。

5、关于.9 图的问题

谷歌官方文档上有.9 图的说明,但是说漏了一些东西。

.9 图有两种存在形式,一种是”源码”形式,一种是经过编译处理的形式。

“源码”形式很容易得到,我们平时写 apk 所用的到就是这种形式,网上也能方便的找到。而 apk 中的.9 图,是经过编译处理后的图。

“源码”形式的.9 图,带有透明的边框,而编译后的.9 图,不再存在这种透明边框,编译后的图存在一种叫做 npTc 数据块的结构中。你不能方便的查看和修改它,但是 Android 系统可以更快的读取和使用它。

以上的情况就会导致,apktool 不能直接去修改.9 图,而需要依赖谷歌官方的工具 – aapt 进行处理。

6、Options

常用的配置
  1. -version, –version

输出当前工具版本

  1. -v, –verbose

输出所有 log,此参数必须放在第一位

  1. -q, –quiet

静默模式,与 -v, –verbose 相反,此参数必须放在第一位

  1. -advance, –advanced

进行每一步操作前,打印相应 log。默认开启。

清空 framework 的配置
  1. -f, –force

强制清除目标目录

  1. -p, –frame-path

指定加载 framework 的目录

反编译的配置
  1. -api, –api-level

指定生成 smali 文件所用的 api 等级,默认使用 targetSdkVersion 版本

  1. -b, –no-debug-info

防止 baksmali 写出调试信息(.local,.param,.line 等)。如果您要比较来自不同版本的同一 APK 的 smali,则首选使用。

  1. -f, –force

如果反编译的目标目录存在,将会被强制清空

  1. –force-manifest

强制反编译 AndroidManifest.xml 文件,优先级高于 -s, –no-src 配置。

  1. –keep-broken-res

如果出现 “Invalid Config Flags Detected. Dropping Resources…” 错误,这表示 apk 中有 apktool 不能识别的结构。可能是 apktool 不支持的更新的 api 版本,亦或者是该 apk 为不规则的 apk。你可以添加此配置,以跳过错误,但后续你需要手动修复这些错误。

  1. -m, –match-original

将各文件处理为最接近原生的形式,将会导致不能备重新打包。

Ps:我试了下,格式确实更接近原生,但是我重新打包也是成功了(打包成功,但并未签名安装)。

  1. –no-assets

不处理和拷贝属于 unknown 的资源文件。

  1. -o, –output

指定输出目录

  1. –only-main-classes

只反编译 apk 根目录下的 dex 文件,如:classes[0-9].dex

通过阅读源码发现,此配置的作用为:反编译根目录下的以 classes 开头,并以 .dex 结尾的 dex 文件,不仅限于 0-9

  1. -p, –frame-path

指定存储和加载 framework 的目录

  1. -r, –no-res

不反编译资源,保留 resources.arsc 为原来的样子,如果你只是需要修改代码,此配置会加快反编译和重新打包的速度。

  1. -s, –no-src

不反编译代码,即不处理 dex 文件。如果你只是需要修改资源,此配置会加快反编译和重新打包的速度。

  1. -t, –frame-tag

使用指定的 framework 进行反编译,前文有述。

重新打包配置
  1. -a, –aapt

指定使用的 aapt,当指定目录未找到 aapt 时,会使用 apktool 自带的 aapt 进行处理。

  1. -api, –api-level

指定处理 smali 文件的 api 版本,默认使用 minSdkVersion 版本

  1. -c, –copy-original

拷贝原始 AndroidManifest.xml and META-INF 到 apk 包体中。将会在 2.5.0 版本移除此功能。

  1. -d, –debug

在 AndroidManifest 加入 debuggable=”true” 配置

此配置,不会覆盖已经存在的 debuggable 配置。

  1. -f, –force-all

当生成的文件存在时,进行强制覆盖

  1. -nc,–no-crunch

此配置会传递给 aapt,参阅:

Expose the aapt –no-crunch option by Novex · Pull Request #1849 · iBotPeaches/Apktool · GitHub

aapt build in apktool is not support new options · Issue #1232 · iBotPeaches/Apktool · GitHub

禁止对资源文件的处理

  1. -o, –output

指定 apk 的输出目录

  1. -p, –frame-path

指定加载 framework 的路径

  1. –use-aapt2

使用 aapt2 进行打包

以上就是 apktool 目前支持的所有配置,下一篇文章,将会进一步深入源码,去看看 apktool 到底都做了些什么。