Mac 反编译 apk 程序

APK,即 Android 应用程序包(Android application package),是 Android 操作系统中用于分发和安装移动应用及中间件的文件格式。一个 Android 应用程序的代码想要在 Android 设备上运行,必须先进行编译,然后打包成为一个被 Android 系统所能识别的文件,其格式便是 APK。一个 APK 文件内包含被编译的代码文件(.dex 文件,即 Dalvik executables),文件资源(resources), assets,证书(certificates),和清单文件(manifest file)。

APK 文件基于 ZIP 格式进行压缩,它与 JAR 文件的构造方式相似。因而,直接解压 APK 文件可以得到一部分内容,如 classes.dex 等。如果要进行更详尽的分析,就需要用到反编译的工具了。

准备工作

下载 apk 反编译组件

需要下载的程序包括:

一些论坛里会把它们称为「APK 反编译三件套」。

前两个程序可以通过 Homebrew 进行安装:

1
brew install apktool dex2jar

Homebrew 同时也会将 openjdk 作为依赖包装好。

JD-GUI 需要点击上面的官网链接下载,选择 jar 格式的即可。

进行反编译

运行 Apktool

安装好 Apktool 后,在终端执行 apktool -h,如果能正确显示帮助信息,则安装正常。
Apktool 的使用方法也很简单,准备好需要反编译的 apk 文件(例如 example.apk),执行

1
apktool d path/to/example.apk

即可进行反编译,这时会生成一个名为 example 的目录,用于存储反编译出的文件。如果要回编译,执行

1
apktool b path/to/example

当然,仅通过回编译得到的 apk 是没有签名的。如果要在安卓手机上安装,还需要进行签名。步骤如下:

1
keytool -genkey -alias tmp.keystore -keyalg RSA -validity 20000 -keystore tmp.keystore

这会生成一个签名文件 tmp.keystore。然后为 apk 签名:

1
jarsigner -verbose -keystore tmp.keystore path/to/example.apk tmp.keystore

这样 example.apk 就可供安装了。

用 dex2jar 将 apk 转成 jar 文件

安装好 dex2jar 后,直接运行:

1
d2j-dex2jar path/to/example.apk

dex2jar 默认将生成 example-dex2jar.jar 文件。

查看源代码

双击打开 JD-GUI.jar,将 example-dex2jar.jar 拖进去就能看到反编译后的源码了。

通过看 Java 源码对比 smali 文件,修改后回编译就 OK 了!

例外情况

当然,不是所有的 APK 应用都可以如此轻松地被反编译。出于保护商业机密等目的,一些软件会通过「加壳」的方法隐藏自身的代码。这时,程序的.dex 文件往往是在运行时才被动态加载的,本文所用的这些静态工具对此无能为力,用它们反编译出的内容并不是程序的真正源码。这就需要借助专业的脱壳破解工具了。


本教程以 macOS 10.13 为例。其它的版本的 Mac 可能在操作上略有差别。

参考文章:
MAC 上反编译 android apk---apktool, dex2jar, jd-jui 安装使用 (含手动签名)

本文更新于 2021 年 8 月 23 日:
旧版的 JD-GUI 与 Java 9 存在兼容性问题,已经在 2019 年被修复了。

本文更新于 2022 年 3 月 10 日:
如果遇到 JD-GUI 无法反编译的情况(也就是直接输出了 Byte code),可以试试其它的工具,例如 Luyten