如何将DEX反编译为Java源代码?

773

如何将Android DEX(VM字节码)文件反编译为相应的Java源代码?


在这里看一下:http://mylifewithandroid.blogspot.com/2009/01/disassembling-dex-files.html。 你会从中获取可能的线索来继续前进。 - Kevin Boyd
有关编程的更新信息可在Coders Hub博客上找到:http://www.coders-hub.com/2013/04/how-to-convert-apk-file-into-source.html - Md Mohsin
如果你有钱,就买 jeb,否则使用 jadx,在这里看看为什么:https://dev59.com/knM_5IYBdhLWcg3wvF3J#28864945 - polym
有一个新的跨平台(Java)和开源工具,可以让您做到这一点,只需检查 bytecodeviewer:https://dev59.com/questions/dW035IYBdhLWcg3wK8wm#36557898 - Gomino
17个回答

972

很容易

获取这些工具:

  1. dex2jar 用于将dex文件转换为jar文件

  2. jd-gui 用于查看jar文件中的java文件

源代码相当易读,因为dex2jar进行了一些优化。

过程:

以下是反编译的步骤:

步骤1:

将test_apk-debug.apk中的classes.dex转换为test_apk-debug_dex2jar.jar

d2j-dex2jar.sh -f -o output_jar.jar apk_to_decompile.apk
d2j-dex2jar.sh -f -o output_jar.jar dex_to_decompile.dex

注1:在Windows机器上,所有.sh脚本都会被替换为.bat脚本。

注2:在Linux/Mac上不要忘记shbash。完整的命令应该是:

sh d2j-dex2jar.sh -f -o output_jar.jar apk_to_decompile.apk 

注意 3:同样,记得给 dex2jar-X.X 目录添加执行权限,例如 sudo chmod -R +x dex2jar-2.0

dex2jar 文档

步骤 2:

在 JD-GUI 中打开 jar 文件。

反编译源代码


65
我尝试了Baksmali和Dex2jar。Dex2Jar+JD-Gui在大多数.dex文件中可以提供完全可读的源代码,因此胜出。 - Jonathan Dumaine
1
嗨,你能分享一下你的做法吗?我会非常感激的。 - Arslan Anwar
3
上面的句子让人想起了什么——它似乎是从这里半引用而来:http://geeknizer.com/decompile-reverse-engineer-android-apk/(或者反过来?)。链接的文章简要介绍了上述工具以及Smali和APKTool。 - AgentKnopf
3
@JonathanDumaine 这取决于情况。如果JAR文件已经混淆并且你只想做一些小修改,那么Backsmali是唯一的选择。额外福利! 使用APKTool,你还可以获取所有XML、图像和其他资源。请参见我的答案 - Alba Mendez
3
@JonathanDumaine 我同意jmendeth的观点,如果你想反编译apk、修改并重新编译它,apktool也是一种可行的方法。虽然使用dex2jar和jd-gui可以使源代码非常易读,但是在没有一些错误的情况下无法重新编译! - darkheir
显示剩余6条评论

143

为了更好地说明,根据您想要实现的目标,您可能会选择两条主要路径:

将Dalvik字节码(dex)反编译为可读的Java源代码。正如Fred所提到的那样,您可以使用dex2jarjd-gui轻松完成此操作。生成的源代码有助于阅读和理解应用程序的功能,但可能无法产生100%可用的代码。换句话说,您可以阅读源代码,但无法真正修改和重新打包它。请注意,如果使用proguard对源代码进行了混淆,则生成的源代码将更加难以理解。

另一个主要选择是将字节码反汇编为smali,这是专门为此目的设计的汇编语言。我发现使用apktool是最简单的方法。一旦安装了apktool,您只需要将其指向apk文件,就会得到应用程序中每个类的smali文件。您可以阅读和修改smali,甚至可以通过从新的Java源生成smali来完全替换类(要做到这一点,您可以使用javac将.java源代码编译为.class文件,然后使用Android的dx编译器将.class文件转换为.dex文件,然后使用baksmali(smali反汇编器)将.dex转换为.smali文件,如this question所述。这里可能有捷径)。完成后,您可以使用apktool轻松地重新打包apk。请注意,apktool不会签署生成的apk,因此您需要像just like any other Android application那样小心处理。
如果您选择使用smali路线,您可能希望尝试使用APK Studio,这是一个IDE,可以自动化上述一些步骤,以帮助您对apk进行反编译、重新编译并在设备上安装。
简而言之,您的选择基本上是将代码反编译为Java,这样更易读但可能无法撤销,或者将其反汇编为smali,这样更难读取但更灵活,可以更改并重新打包修改后的应用程序。您选择哪种方法将取决于您想要实现的目标。
最后,dare 的建议也值得注意。它是一个重定向工具,将 .dex 和 .apk 文件转换为 java .class 文件,以便可以使用典型的 java 静态分析工具进行分析。

尝试使用APK Studio,是一个很棒的选择。 - Sideeg MoHammed

62

我实际上推荐您去这里: https://github.com/JesusFreke/smali

它提供了BAKSMALI,这是一个非常优秀的DEX文件反编译工具。 它由JesusFreke制作,他曾创建过Android著名的ROM。


3
Smali是一种类似汇编的语言,基于Dalvik IL,它无法直接转换为Java。 - reflog
@endryha 目前没有工具能够做到这一点。请参考此问题获取更多信息。 - Alba Mendez
1
代码,代码,代码……为什么只有代码?如果您使用APKTool,您可以获取_所有_内容!而且它就像./apktool d myprogram.apk一样简单。请参见我的答案 - Alba Mendez

41

因为 Dheeraj Bhaskar 的回答相对较旧,许多年已经过去。

这里是我的最新回答(2019年):

主要逻辑

dex 转换到 java 源代码,目前有两种解决方案:

  • 一步:直接将 dex 转换为 java 源代码
  • 两步:先将 dex 转换为 jar,再将 jar 转换为 java 源代码

一步解决方案:将 dex 直接转换为 java 源代码

工具

过程

  1. 下载 jadx-0.9.0.zip,解压缩后,在bin文件夹中可以看到命令行jadx或 GUI 版本 jadx-gui,双击运行 GUI 版本:jadx-gui

  1. 打开dex文件

然后可以显示 java 源代码:

  1. 文件 -> 保存为 gradle 项目

然后得到了 java 源代码:


两步解决方案

第一步:dex 转换为 jar

工具

过程

下载 dex2jar zip,解压得到 d2j-dex2jar.sh,然后:

  • apk 转为 jarsh d2j-dex2jar.sh -f ~/path/to/apk_to_decompile.apk
  • dex 转为 jarsh d2j-dex2jar.sh -f ~/path/to/dex_to_decompile.dex

例如:

➜  v3.4.8 /Users/crifan/dev/dev_tool/android/reverse_engineering/dex-tools/dex-tools-2.1-SNAPSHOT/d2j-dex2jar.sh -f com.huili.readingclub8825612.dex
dex2jar com.huili.readingclub8825612.dex -> ./com.huili.readingclub8825612-dex2jar.jar
➜  v3.4.8 ll
-rw-------  1 crifan  staff   9.5M  3 21 10:00 com.huili.readingclub8825612-dex2jar.jar
-rw-------  1 crifan  staff   8.4M  3 19 14:04 com.huili.readingclub8825612.dex

步骤2:将 jar 转换为 java源代码

工具

过程

这里演示了如何使用 Procyon 将 jar 转换为 java 源代码:

下载 procyon-decompiler-0.5.34.jar

然后使用以下语法:

java -jar /path/to/procyon-decompiler-0.5.34.jar -jar your_to_decompile.jar -o outputFolderName

例如:

java -jar /Users/crifan/dev/dev_tool/android/reverse_engineering/Procyon/procyon-decompiler-0.5.34.jar -jar com.huili.readingclub8825612-dex2jar.jar -o com.huili.readingclub8825612

使用编辑器 VSCode 打开导出的源代码,看起来像这样:

结论

转换正确性 : Jadx > Procyon > CRF > JD-GUI

建议使用:(一步解决方案) Jadx


有关更详细的说明,请参阅我的在线中文电子书:安卓应用的安全和破解


有点奇怪,但是如果我尝试通过以下命令在Windows上执行1步(将dex转换为jar),dex2jar-2.0>d2j-dex2jar.bat -f D:\android\some_dex_file.dex,就会出现异常:java.io.IOException: the src file not a .dex or zip file - Сергей
@Сергей,你能试一下:d2j-dex2jar.bat "D:\android\some_dex_file.dex",可以吗? - crifan
是的,我确实尝试过 >d2j-dex2jar.bat file.dex,但不行。也许是因为我的 .dex 文件是从 dalvik-cache 复制过来的? - Сергей
1
@Сергей 是的,最有可能的原因是你所说的dex是从dalvik-cache复制的,应该是dex是从apk反编译而来的 - crifan
1
我会写我的代码,谁知道你可能是个中共党员。 - Yanjan. Kaf.
显示剩余2条评论

32

fredanswer的更完整版本:

手动方式

首先,您需要一个工具来提取DEX上所有(编译后的)类到JAR文件中。
有一个叫做dex2jar的工具,由一位中国学生开发。

然后,您可以使用jd-gui将JAR文件中的类反编译为源代码。
生成的源代码应该非常易读,因为dex2jar应用了一些优化。

自动方式

你可以使用APKTool。它将自动提取所有类(.dex)和资源(.asrc),然后将二进制XML转换为可读的XML,并且还会为您反汇编类。 反汇编始终比反编译更加稳健,尤其是对于使用Pro Guard混淆的JAR文件!
只需告诉APKTool将APK解码到目录中,然后修改所需内容,最后将其重新编码为APK即可。就这样。

重要提示:APKTool可以反汇编,但不能反编译
生成的代码不是Java源代码。
但如果您熟悉jasmin,您应该能够阅读甚至编辑它。
如果您需要Java源代码,请使用手动方式


26
有时候,使用 dex2jar/apktool 时会出现损坏的代码,特别是在循环中。为了避免这种情况,可以使用 jadx,它将 dalvik 字节码反编译为 Java 源代码,而不像 dex2jar 那样先创建一个 .jar/.class 文件(我认为 apktool 使用 dex2jar)。它还是开源的,并且正在积极开发中。甚至还有一个 GUI,适合 GUI 爱好者。试试吧!

我想jadx没有编译选项,但代码可读性还是不错的。 - Buddy
@EnesBattal 你的意思是像这样 javac "$(find . -name '*.java')" 吗? - polym
如何生成APK?将类放入APK中,进行zipalign、签名等操作。 - Buddy
@EnesBattal 好的,你可以帮忙实现它 - 否则你可以使用apktool..或者使用Android工具进行zipalign/签名。 - polym
这个回答让人觉得它似乎从不使用dex2jar工具,而是直接从dex反编译到Java源代码。真的是这样吗?如果是这样,那么它如何能够打开普通的桌面jar文件呢?(我刚试了一下,它可以工作)它是否有一个单独的反编译器用于dex和jar文件? - Venryx
显示剩余2条评论

19

我曾经使用过以下工具:

  1. dex2jar + jd-gui
  2. javadecompilers.com
  3. enjarify
  4. Apktool

但是没有一个能够胜过谷歌自己的工具:

1)Android Studio 2.x: build> analyze apk 进入图片描述

2)Android Studio 3.0: Profile or Debug APK 进入图片描述 进入图片描述


2
为Enjarify点个赞。根据我的个人经验,与d2j相比,Enjarify的结果更好。 - qre0ct

15

除了之前提到的工具外,还有一个工具:DED首页

如何安装和一些说明:安装说明

它被用于一项非常有趣的研究,该研究关注市场上顶尖应用程序的安全性(与前面内容无关,只是如果您好奇的话):《Android应用程序安全调查》


看起来很有前途。它能直接从APK反编译Java代码吗?那么混淆的Java代码呢? - sandalone

13

一旦您下载了APK文件,您需要执行以下步骤才能获得可编辑的Java代码/文档:

  1. 将您的APK文件转换为zip格式(在开始下载时不要选择“保存”,只需选择“另存为”并将扩展名命名为.zip),这样可以避免使用APKTOOL...
  2. 解压缩zip文件,在其中找到somefilename.dex。现在我们需要将dex -> .class进行转换
  3. 为此,您需要 "dex2jar"(您可以从http://code.google.com/p/dex2jar/下载它,在提取后,在命令提示符中必须像这样指定:[D:\dex2jar-0.09>dex2jar somefilename.dex](请记住,您的somefilename.dex必须位于您放置dex2jar的相同文件夹中)
  4. http://www.viralpatel.net/blogs/download/jad/jad.zip下载jad并提取它。提取后,您可以看到两个文件,如“jad.exe”和“Readme.txt”(有时可能是“jad.txt”而不是“jad.exe”,因此只需将其扩展名更改为.exe即可运行)
  5. 最后,在命令提示符中,您必须像这样指定[D:\jad>jad -sjava yourfilename.class],它将解析您的类文件并将其转换为可编辑的Java文档。

9

Android逆向工程是可行的。按照以下步骤获取.apk文件中的.java文件。

步骤1:使用dex2jar

  • 从.apk文件生成.jar文件
  • 命令:dex2jar sampleApp.apk

步骤2:使用JD-GUI反编译.jar文件

  • 它会反编译.class文件,即我们从apk中得到混淆的.java文件。

但如果我重新编译所有反编译的源代码,它就无法运行,编译器会显示很多错误。 - user1129139
有没有可用的解决方案可以反编译 Android Java 源代码并在 Eclipse 中运行? - user1129139
2
“反向工程”并不一定意味着“反编译”。事实上,ProGuard混淆的JAR包无法正确地进行反编译。 - Alba Mendez
如果你正在处理混淆代码,最好只是将其反汇编。你不会得到Java源代码,但你总是能够查看/修改代码。请参见我的答案 - Alba Mendez
我建议同时进行反编译和反汇编。反编译后的代码更易于理解,但所有修改都需要使用反汇编版本完成。如果使用了proguard,则尤其如此。我发现dex2jar与jd-gui结合使用是最好的反编译工具。 - Mikko Rantalainen
如何使用JD-GUI反编译.jar文件? - Arnold Brown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接