如何将Android DEX(虚拟机字节码)文件反编译成相应的Java源代码?
当前回答
弗雷德回答的更完整版本:
手动方式
首先,您需要一个工具将DEX上的所有(已编译的)类提取到JAR中。 有一个叫dex2jar的,是一个中国学生做的。
然后,您可以使用jd-gui将JAR上的类反编译为源代码。 由于dex2jar应用了一些优化,因此得到的源代码应该非常易读。
自动方式
你可以使用APKTool。它将自动提取所有的类(.dex)、资源(.asrc),然后它将二进制XML转换为人类可读的XML,它还将为您分解类。 反汇编总是比反汇编更健壮,特别是使用 jar与Pro Guard混淆!
只需告诉APKTool解码APK到一个目录,然后修改你想要的, 最后编码回APK。这是所有。
重点:APKTool可以分解。它不会反编译。 生成的代码不是Java源代码。 但是如果您熟悉jasmin,您应该能够阅读它,甚至可以编辑它。 如果你想要Java源码,请参照手动方式。
其他回答
由于没有人提到这一点,还有一个工具:DED主页
安装指南和一些说明:安装。
它被用于一个非常有趣的关于顶级市场应用程序安全性的研究(不是真的相关,如果你好奇的话):Android应用程序安全性调查
这可以通过以下五个步骤来完成:
这个gem自动为您完成这些工作,甚至安装所需的工具
将apk文件转换为zip 解压缩文件 从中提取classes.dex 使用dex to jar将classes.dex转换为jar文件 使用jadx GUI打开jar文件作为Java源代码
很容易
获取这些工具:
Dex2jar将dex文件转换为jar文件 以查看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上不要忘记sh或bash。完整的命令应该是:
sh d2j-dex2jar.sh -f -o output_jar.jar apk_to_decompile.apk
注意3:另外,请记住向dex2jar-X添加执行权限。例如sudo chmod -R + X dex2jar-2.0
dex2jar文档
步骤2:
在JD-GUI中打开罐子
最近Debian有Python包androguard:
Description-en: full Python tool to play with Android files
Androguard is a full Python tool to play with Android files.
* DEX, ODEX
* APK
* Android's binary xml
* Android resources
* Disassemble DEX/ODEX bytecodes
* Decompiler for DEX/ODEX files
安装相应的软件包:
sudo apt-get install androguard python-networkx
反编译DEX文件:
$ androdd -i classes.dex -o ./dir-for-output
从Apk +反编译中提取classes.dex:
$ androdd -i app.apk -o ./dir-for-output
Apk文件就是Java的JAR文件,你可以通过以下方法从JAR文件中提取文件:
$ unzip app.apk -d ./dir-for-output
在使用dex2jar/apktool时,有时会出现坏代码,最明显的是在循环中。为了避免这种情况,可以使用jadx,它可以将dalvik字节码反编译成java源代码,而不需要像dex2jar那样先创建.jar/.class文件(我认为apktool使用dex2jar)。它也是开源的,正在积极开发中。它甚至有一个GUI,专为GUI爱好者设计。试一试!
推荐文章
- Android Studio, logcat在应用程序关闭后清理
- Intellij IDEA Java类在保存时不能自动编译
- 何时使用Mockito.verify()?
- 在maven中安装mvn到底做什么
- 在android中从上下文获取活动
- 不可变与不可修改的集合
- 如何在JSON中使用杰克逊更改字段名
- GSON -日期格式
- 如何从线程捕获异常
- 无法解析主机"<URL here>"没有与主机名关联的地址
- getActivity()在Fragment函数中返回null
- 如何在Java中打印二叉树图?
- 按钮背景是透明的
- String.format()在Java中格式化双重格式
- 在Mac OS X上哪里安装Android SDK ?