上一篇 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文档中的内容,此处不再详述。
(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进行反编译,注意查看log中的区别。
同时需要说明的是,当你使用了指定的framework进行反编译后,想要重新打包apk时,不需要再进行framework的指定了,apktool会自动使用反编译时使用的framework进行重新打包。
5、关于.9图的问题
谷歌官方文档上有.9图的说明,但是说漏了一些东西。
.9图有两种存在形式,一种是"源码"形式,一种是经过编译处理的形式。
"源码"形式很容易得到,我们平时写apk所用的到就是这种形式,网上也能方便的找到。而apk中的.9图,是经过编译处理后的图。
"源码"形式的.9图,带有透明的边框,而编译后的.9图,不再存在这种透明边框,编译后的图存在一种叫做 npTc 数据块的结构中。你不能方便的查看和修改它,但是Android系统可以更快的读取和使用它。
以上的情况就会导致,apktool不能直接去修改.9图,而需要依赖谷歌官方的工具 -- aapt进行处理。
6、Options
常用的配置
(1)-version, --version
输出当前工具版本
(2)-v, --verbose
输出所有log,此参数必须放在第一位
(3)-q, --quiet
静默模式,与 -v, --verbose 相反,此参数必须放在第一位
(4)-advance, --advanced
进行每一步操作前,打印相应log。默认开启。
清空framework的配置
(1)-f, --force
强制清除目标目录
(2)-p, --frame-path
指定加载framework的目录
反编译的配置
(1)-api, --api-level
指定生成smali文件所用的api等级,默认使用targetSdkVersion版本
(2)-b, --no-debug-info
防止baksmali写出调试信息(.local,.param,.line等)。如果您要比较来自不同版本的同一APK的smali,则首选使用。
(3)-f, --force
如果反编译的目标目录存在,将会被强制清空
(4)--force-manifest
强制反编译 AndroidManifest.xml文件,优先级高于 -s, --no-src 配置。
(5)--keep-broken-res
如果出现 "Invalid Config Flags Detected. Dropping Resources..." 错误,这表示apk中有apktool不能识别的结构。可能是apktool不支持的更新的api版本,亦或者是该apk为不规则的apk。你可以添加此配置,以跳过错误,但后续你需要手动修复这些错误。
(6)-m, --match-original
将各文件处理为最接近原生的形式,将会导致不能备重新打包。
Ps:我试了下,格式确实更接近原生,但是我重新打包也是成功了(打包成功,但并未签名安装)。
(7)--no-assets
不处理和拷贝属于 unknown 的资源文件。
(8)-o, --output
指定输出目录
(9)--only-main-classes
只反编译apk根目录下的dex文件,如:classes[0-9].dex
通过阅读源码发现,此配置的作用为:反编译根目录下的以 classes 开头,并以 .dex 结尾的dex文件,不仅限于0-9
(10)-p, --frame-path
指定存储和加载framework的目录
(11)-r, --no-res
不反编译资源,保留 resources.arsc 为原来的样子,如果你只是需要修改代码,此配置会加快反编译和重新打包的速度。
(12)-s, --no-src
不反编译代码,即不处理 dex文件。如果你只是需要修改资源,此配置会加快反编译和重新打包的速度。
(13)-t, --frame-tag
使用指定的framework进行反编译,前文有述。
重新打包配置
(1)-a, --aapt
指定使用的aapt,当指定目录未找到aapt时,会使用apktool自带的aapt进行处理。
(2)-api, --api-level
指定处理smali文件的api版本,默认使用minSdkVersion版本
(3)-c, --copy-original
拷贝原始 AndroidManifest.xml and META-INF 到apk包体中。将会在2.5.0版本移除此功能。
(4)-d, --debug
在 AndroidManifest 加入 debuggable="true" 配置
此配置,不会覆盖已经存在的debuggable配置。
(5)-f, --force-all
当生成的文件存在时,进行强制覆盖
(6)-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
禁止对资源文件的处理
(7)-o, --output
指定apk的输出目录
(8)-p, --frame-path
指定加载framework的路径
(9)--use-aapt2
使用aapt2进行打包
以上就是apktool目前支持的所有配置,下一篇文章,将会进一步深入源码,去看看apktool到底都做了些什么。