知道了Apktool 的基本用法Apktool 使用教程,以及Apktool的全部参数配置Apktool 参数详解之后,对于Apktool的用法,可以说已经基本搞定,不过源码的阅读也是比不可少的,懂得源码,能改会改,才是解决棘手问题的根本能力。
注意:本文使用的源码为github上拉取的最新代码,2.4.2版本,目前暂未发布。 -- 2020年3月18日
1、查看apktool.jar的入口类
通过查看jar包的Manifest.MF文件,看到入口类为brut.apktool.Main
apktool.jar的Manifest文件
2、使用Android studio打开apktool的源码
项目结构
3、找到入口类 brut.apktool.Main
main函数主要做了以下事情,很简单,此处不详述。
(1)设置系统属性 System.setProperty("java.awt.headless", "true");
这里的system,系统指的是 JRE (runtime)system,不是指 OS。
(2)new一个命令行解析器,后续进行命令行参数的解析
(3)初始化配置类,包括各种配置,日志输出等级,是否处理资源文件等等
分所属分别存储在 normalOptions;DecodeOptions;BuildOptions;等变量中
(4)设置日志级别,初始化Logger,设置是否打印步骤日志
(5)解析到底是反编译、重新打包还是安装framework等参数
4、反编译资源
private static void cmdDecode(CommandLine cli)
(1)创建核心类ApkDecoder,其构造方法中,new了一个Androlib类
(2)解析反编译相关的配置,都设置到decoder中备用
解析配置
(3)创建输出目录
默认以apk名字作为目录名
(4)调用反编译核心方法
反编译核心方法
(5)decod方法
将--keep-broken-res配置值,存入AndrolibResources类中
检查输出目录,输入文件是否OK,不OK抛出异常
OK则创建输出目录
检查
输出我们最常见到的一句log
版本信息等log
之后就开始主要的反编译逻辑了。
(6)处理资源
资源处理流程
(7)具体的解析流程,网上各位大神分析的很到位。这里推荐一个,部分注释也是参考了这位的帖子内容!
ApkTool项目解析resources.arsc详解 - 掘金
5、反编译源码
(1)反编译最基础的classes.dex文件
反编译主dex
(2)输出log,开始反编译dex
Baksmaling log
进入 SmaliDecoder 的 decode 方法。
最终执行Baksmali库的方法进行反编译
反编译代码
具体解析过程,后续我准备再写一篇关于 Baksmali 文章吧。
解析 dex 可以参考:Android逆向笔记 —— DEX 文件格式解析 - 掘金
(3)处理多个dex,和解析一个dex一个道理,不再重复
处理多个dex
6、处理assets和libs
处理未经压缩文件
7、处理未知文件
处理未知文件
未知文件指非apk固定文件的内容:
"classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "r", "R", "lib", "libs", "assets", "META-INF", "kotlin"
判断是否为未知文件内容
将未知文件拷贝到 unknown 目录,并且记录下这些文件。
记录不压缩的文件,读取文件压缩等级,当文件压缩等级为不压缩或者文件符合下列类型时,不进行压缩。
不压缩类型文件
记录不压缩文件
记录不压缩文件
处理原始文件,如果你配置了 -c, --copy-original ,则会将 AndroidManifest.xml 和 META-INF 拷贝到 original 目录下。如下图:
处理原始文件
original目录
8、生成 apktool.yml 文件
生成 apktool.yml 文件
apktool.ym 包含的内容
apktool.yml 内容示例如下:
apktool.yml内容
(1)putUsesFramework(meta); 记录使用的framework ---- usesFramework配置项
(2)putSdkInfo(meta); 记录sdkversion信息。 ---- sdkInfo配置项
(3)putPackageInfo(meta);记录packageInfo。 ---- packageInfo配置项
(4)putVersionInfo(meta); 记录包体versioncode,versionname ---- versionInfo配置项
(5)putSharedLibraryInfo(meta);记录是否是一个库。 ---- sharedLibrary配置项
(6)putSparseResourcesInfo(meta); 这个暂时没去了解。---- sparseResources配置项
不过看注释,是与aapt2有关的东西,aapt1忽略这个。估计是aapt1和aapt2之间的处理差异,记录下来,方便重新打包时进行不同的处理。
sparseResources
(7)putUnknownInfo(meta); 记录未知文件。 ---- unknownFiles配置项
(8)putFileCompressionInfo(meta);记录文件压缩信息。 ---- doNotCompress配置项
8、小结
粗浅的写了一些流程上的东西,目前只是总结了反编译过程。具体的一些细节,比如 resources.arsc 的解析过程,我也是参考网上大佬的帖子来进行一步步解析的,所以没有自己再去重复写,自己也肯定没有大佬们写的好。另外dex的反编译因为apktool也是直接使用的baksmali库来进行的,后续自己阅读的时候再另起帖子说说。
下面一篇就还是写写重新打包就算完成任务啦。
附上apktool和baksmali的github地址
GitHub - iBotPeaches/Apktool: A tool for reverse engineering Android apk files