0%

Mac 反编译 apk 程序

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

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

准备工作

下载最新的 JDK

前往 ORACLE 官网,在底部找到 Download Java for Developers,点击该链接,在打开的页面中找到 JDK,选择 Download,然后下载对应的版本即可。

配置 JDK

下载完成后,打开 dmg 镜像进行安装。JDK 会被安装到 /Library/Java/JavaVirtualMachines 目录下。为了能在终端正确运行最新的 JDK,需要配置环境变量。在 ~/.bash_profile 中增加以下内容:

1
2
3
4
5
6
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home
PATH=$JAVA_HOME/bin:$PATH:.
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.
export JAVA_HOME
export PATH
export CLASSPATH

其中,将 jdk1.8.0_40.jdk 换成你所安装的 JDK 对应的版本和目录。修改完成后,重开终端或使用

1
source ~/.bash_profile

使环境变量生效。

下载 apk 反编译组件

需要下载的程序包括:

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

进行反编译

运行 Apktool

按照官网上的教程,将下载 Apktool 后得到的 Shell 脚本和 apktool.jar 移动到 /usr/local/bin,然后在终端执行 apktool -h,如果能正确显示帮助信息,则安装正常。
Apktool 的使用方法也很简单,准备好需要反编译的 apk 文件(例如 example.apk),执行

1
apktool d path/to/example.apk

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

1
apktool b path/to/example

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

1
2
keytool -genkey -alias tmp.keystore -keyalg RSA -validity 20000 -keystore tmp.keystore
jarsigner -verbose -keystore tmp.keystore -signedjar path/to/example.apk path/to/example_signed.apk tmp.keystore

这会生成一个签名文件 tmp.keystore 和可供安装的 example_signed.apk

用 dex2jar 将 apk 转成 jar 文件

下载 dex2jar 的 releases 版本后,解压进入文件夹,然后运行:

1
./d2j-dex2jar.sh path/to/example.apk

在 dex2jar 目录下将得到 example-dex2jar.jar 文件

查看源代码

打开 JD-GUI.app,将 example-dex2jar.jar 拖进去就能看到源码了。
需要注意的是,如果你使用了 Java9,打开 JD-GUI 时可能会出现问题,解决方法是修改 JD-GUI.app/Contents/Info.plist,找到

1
2
<key>VMOptions</key>
<string>-Xms512m</string>

改为

1
2
<key>VMOptions</key>
<string>-Xms512m --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED</string>

即可正常启动。
通过看 Java 源码对比 smali 文件,修改后回编译就 ok 了!


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

参考文章:
MAC 安装 JDK 及环境变量配置
MAC 上反编译 android apk---apktool, dex2jar, jd-jui 安装使用 (含手动签名)
apk 反编译获取完整源码 及 apk 反编译后的处理
Java 9 Compatibility

🍭支持一根棒棒糖!
张书樵 微信

微信

张书樵 支付宝

支付宝