欢迎光临
专注android技术,聚焦行业精粹,传扬中国传统文化,我们一直在努力

ApkTool 源码分析

1、ApkTool介绍

它是一个为逆向工程师打造的用于反编译Android 二进制 app的工具。它可以将资源解码为几乎原始的形式,并在修改之后重建它们。

1.1、功能

  • 将资源反编译为几乎原始的格式(包括resources.arsc、classes.dex、9.png和XML文件)
  • 重新编译这些反编译后的资源为二进制apk/jar
  • 可以处理依赖框架资源的APK
  • Smali 调试 (在 2.1.0 版本已经移除,建议替换为idea或android studio插件IdeaSmali)

1.2、源码工程介绍

Apktool是一个Android 工程,它包含了一些子工程和一些依赖:

  • brut.apktool.lib ——(apktool的library库)
  • brut.apktool.cli —— apktool的入口,程序命令的接口定义在这里
  • brut.j.dir —— 工具
  • brut.j.util —— 工具
  • brut.j.common —— 工具

工程源码下载地址:https://github.com/iBotPeaches/Apktool

1.3、构建步骤

我们用gradle来构建会非常简单,首先你要clone远程代码仓库;

  • git clone git://github.com/iBotPeaches/Apktool.git
  • cd Apktool
  • 接下来unix系统用 ./gradlew 或者windows系统用 gradlew.bat
  • [./gradlew][gradlew.bat] build shadowJar – 编译Apktool工程,和生成最终的二进制可运行文件

构建完成后你可以在以下目录找到一个jar文件

./brut.apktool/apktool-cli/build/libs/apktool-xxxxx.jar

2、ApkTool 工程源码分析

2.1、能解析的文件格式和对应的工具

  • 对于dex文件,apktool使用了dexlib2来进行读/修改/写操作。使用baksmali库反编译dex文件为smali格式。同时使用smali工具回编译smali到dex格式,再通过dexlib2写为dex文件
  • 对于apk里面的所有xml格式,apktool采用了自己解析的方式,它的主要实现在AXmlResourceParser里面。并结合xpp3库读取解析后的xml文件信息。在回编译的时候使用Android的aapt工具。
  • resources.arsc文件解析也采用了自己解析的方式,主要实现在ARSCDecoder类里面,回编译的时候使用了aapt
  • 其它的一些assets、so、META-INF都是直接copy

2.2、ApkTool的反编译流程

这幅图描述了apktool如何将apk里面文件转换为可阅读文件的过程,里面使用到了上面介绍的工具。结合这张图在阅读源码上帮助会很大。

整体来说apktool对resources.arsc和xml这两种二进制格式文件采用了自己解析的方式,这些二进制文件的格式可以参考这篇文章:https://blog.csdn.net/jiangwei0910410003/article/details/50628894

我也非常开心买了作者的这本书:《Android应用安全防护和逆向分析》,也非常推荐这本书,全网只有它对Android二进制文件的分析最为和详细。

2.3、ApkTool工程类图结构

Apktool工程的核心在于decorder文件夹下面的这些解析工具类,有兴趣的同学可以详细研究一下。

它也依赖了一些第三方库:

  • xpp3: XmlPullParser,以流的方式解析xml文件
  • aapt: android提供的资源打包工具,后面官方升级了并默认推荐使用aapt2版本,不过目前aapt仍然广泛使用。
  • dexlib2:操作dex文件
  • smali:回编译smali文件到dexlib2可识别格式,结合dexlib2smali文件转为dex文件
  • baksmali:将dex转smali

 

3、ApkTool常见打包问题

3.1、error: No resource identifier found for attribute ‘compileSdkVersion’ in package ‘android’

错误日志:

解决方案:

在运行打包之前先执行下面的命令:

原因分析:

本地有两个版本的apktool,首先用旧版本的apktool打包成功,然后再用新版本的apktool打包就出问题。

原因是旧版本的apktool先下载了对应的framework的apk到本地,再用新版本apktool打包时发现本地有framework.apk就直接使用而不会去更新framework.apk,但是该旧版本的framework.apk可能和新版本apktool不兼容,所以出现上面的问题了。

详细分析:

根据apktool官方的介绍,也印证了我们上面的错误分析结论:

Apktool官方对Frameworks的介绍:https://ibotpeaches.github.io/Apktool/documentation/

官方的意思是:

Apktool和framework.apk是绑定在一起的。这个文件在被使用的时候会拷贝到$Home/apktool/framework/1.apk。

注意:Apktool不关心对应路径下面的framework的版本是多少。它会假设这个framework是最新的,所以apktool升级的时候需要删除旧的framework

apktool依赖的framework在不同的系统上会放在不同的位置:

  • unix – $HOME/.local/share/apktool
  • windows – %UserProfile%\AppData\Local\apktool
  • mac – $HOME/Library/apktool

另一种推荐的解决方案:

如果你本地有多个版本的apktool,或你需要有多个不同的framework同时存在。你需要更简单的方法来切换这些framework,具体方法如下:

你需要为这些多个不同的framework打上对应的tag

在使用apktool解包的时候,这样使用:

你不需要在合包的时候选择framework的tag,apktool会自动使用和解包时相同的tag。

4、ApkTool 断点调试

学习apktool源码最快的方式是可以断点调试里面的代码。让ApkTool可以断点调试需要以下几步:

1、Android Studio菜单Run > Edit Configuration… > 添加一个Application类型的Configuration,配置如下:

  • 设置Main class 为 brut.apktool.Main
  • Program arguments 这里是apktool解包或合包的参数,我们可以先预置一个apk包在工程目录,然后对它进行解包操作。例如:d apk/game.apk -o apk/output/
  • Working directory 为Apktool的工程目录
  • use classpath of module: 选定apktool-cli

2、菜单上点击debug运行刚刚添加的config(apktool-run)

就可以顺利断点到你想要的位置了

赞(2) 打赏
未经允许不得转载:花花鞋 » ApkTool 源码分析

评论 抢沙发

国内精品Android技术社区

专注android技术,聚焦行业精粹,传扬中国传统文化,我们一直在努力

联系我们

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册