miao~
miao~
发布于 2024-03-28 / 5 阅读
0

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。

    (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

GitHub - JesusFreke/smali: smali/baksmali