Apktool 源码-反编译

知道了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。

  1. new一个命令行解析器,后续进行命令行参数的解析

  2. 初始化配置类,包括各种配置,日志输出等级,是否处理资源文件等等

分所属分别存储在 normalOptions;DecodeOptions;BuildOptions;等变量中

  1. 设置日志级别,初始化Logger,设置是否打印步骤日志

  2. 解析到底是反编译、重新打包还是安装framework等参数

4、反编译资源

private static void cmdDecode(CommandLine cli)

  1. 创建核心类ApkDecoder,其构造方法中,new了一个Androlib类

  2. 解析反编译相关的配置,都设置到decoder中备用

解析配置
  1. 创建输出目录

默认以apk名字作为目录名
  1. 调用反编译核心方法

    反编译核心方法
  2. decod方法

将–keep-broken-res配置值,存入AndrolibResources类中

检查输出目录,输入文件是否OK,不OK抛出异常

OK则创建输出目录

检查

输出我们最常见到的一句log

版本信息等log

之后就开始主要的反编译逻辑了。

  1. 处理资源


资源处理流程

  1. 具体的解析流程,网上各位大神分析的很到位。这里推荐一个,部分注释也是参考了这位的帖子内容!

ApkTool项目解析resources.arsc详解 - 掘金

5、反编译源码

  1. 反编译最基础的classes.dex文件

反编译主dex
  1. 输出log,开始反编译dex

Baksmaling log

进入 SmaliDecoder 的 decode 方法。

最终执行Baksmali库的方法进行反编译

反编译代码

具体解析过程,后续我准备再写一篇关于 Baksmali 文章吧。

解析 dex 可以参考:Android逆向笔记 —— DEX 文件格式解析 - 掘金

  1. 处理多个dex,和解析一个dex一个道理,不再重复

处理多个dex

6、处理assets和libs

处理未经压缩文件

7、处理未知文件

处理未知文件

未知文件指非apk固定文件的内容:

“classes.dex”, “AndroidManifest.xml”, “resources.arsc”, “res”, “r”, “R”, “lib”, “libs”, “assets”, “META-INF”, “kotlin”

判断是否为未知文件内容

将未知文件拷贝到 unknown 目录,并且记录下这些文件。

记录不压缩的文件,读取文件压缩等级,当文件压缩等级为不压缩或者文件符合下列类型时,不进行压缩。

不压缩类型文件

记录不压缩文件
![](https://images.664663.xyz/images/2025/06/c61b2d8d858c70a4b361511dd89f4c3f.png)
记录不压缩文件

处理原始文件,如果你配置了 -c, –copy-original ,则会将 AndroidManifest.xml 和 META-INF 拷贝到 original 目录下。如下图:

处理原始文件
![](https://images.664663.xyz/images/2025/06/10a71e45f81069812802a3f92d8bf110.png)
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
  1. putUnknownInfo(meta); 记录未知文件。 —- unknownFiles配置项

  2. putFileCompressionInfo(meta);记录文件压缩信息。 —- doNotCompress配置项

8、小结

粗浅的写了一些流程上的东西,目前只是总结了反编译过程。具体的一些细节,比如 resources.arsc 的解析过程,我也是参考网上大佬的帖子来进行一步步解析的,所以没有自己再去重复写,自己也肯定没有大佬们写的好。另外dex的反编译因为apktool也是直接使用的baksmali库来进行的,后续自己阅读的时候再另起帖子说说。

下面一篇就还是写写重新打包就算完成任务啦。

附上apktool和baksmali的github地址

GitHub - iBotPeaches/Apktool: A tool for reverse engineering Android apk files

GitHub - JesusFreke/smali: smali/baksmali