从APK文件中获取源代码的方法有哪些?

1471

我的笔记本电脑上的硬盘刚刚崩溃了,我失去了过去两个月一直在开发的应用程序的所有源代码。我手头只有一份存储在邮件中的APK文件,当时是给朋友发送的。

有没有办法从这个APK文件中提取我的源代码呢?


36
FYI 这里有在线反编译检查工具 链接 - edwin
18
这是否意味着我们可以获得价值百万美元的应用程序(如WhatsApp或Facebook)的源代码? 这一切都是开源的吗? - Faizan
6
@Faizan,你听说过ProGuard吗? - Vishwajit Palankar
3
问题的措辞包含了无关的生活故事细节,因此可能会被解释为“推荐一种工具”。然而,答案可能是javac -decompile,这将符合SO准则。在我看来,答案是“离题的”,而不是问题本身。 - SwiftArchitect
2
这篇文章中,他们解释了如何逆向工程Pokemon Go。 - anders
显示剩余9条评论
33个回答

1764

最简单的方法:使用在线工具Decompiler,上传apk文件并获取源代码。


逐步解码 .apk 文件的过程:

第一步:

  1. 新建一个文件夹,将想要解码的 .apk 文件复制到该文件夹中。

  2. 现在将此 .apk 文件的扩展名改为 .zip(从 filename.apk 改为 filename.zip)并保存。现在您可以访问 classes.dex 文件。此时,您可以看到可绘制内容,但无法查看 .xml 和 .java 文件。

第二步:

  1. 现在在相同的文件夹或新文件夹中提取此 .zip 文件。

  2. 下载 dex2jar(不要下载代码,点击右侧的发布按钮,然后下载名为 dex2jar-X.X.zip 的文件),并将其提取到相同的文件夹或新文件夹中。

  3. 将 classes.dex 文件移动到 dex2jar 文件夹中。

  4. 现在打开命令提示符,并将目录更改为该文件夹。然后写入 d2j-dex2jar classes.dex (对于 Mac 或 Ubuntu,请写入 ./d2j-dex2jar.sh classes.dex),然后按 Enter。您现在在同一文件夹中有 classes.dex.dex2jar 文件。

  5. 下载 java 反编译器,右键单击 jd-gui,点击“打开文件”,并打开该文件夹中的 classes.dex.dex2jar 文件:现在您可以得到类文件。

  • 保存所有这些类文件(在jd-gui中,点击“文件”->“全部源代码保存”)按src名称。此时,您可以得到Java代码,但.xml文件仍然无法阅读。

  • 步骤3:

    现在打开另一个新文件夹

    1. 放入要解码的.apk文件

    2. 下载最新版本的apktool apktool install window(两者可以从同一个链接下载),并将它们放在同一个文件夹中

    3. 打开命令提示符

    4. 现在运行命令apktool if framework-res.apk(如果没有,请在此处获取),然后运行

    5. apktool d myApp.apk (myApp.apk表示要解码的文件名)

    现在您会在那个文件夹中得到一个文件夹,并且可以轻松阅读.xml文件。

    步骤4:

    这不是任何步骤,只需将两个文件夹(两个新文件夹)的内容复制到单个文件夹中

    并享受源代码!


    26
    在第三步的第5点中,我遇到了以下错误:无法访问jar文件E:\apktojava\testt\apktool.jar。 - user1025050
    63
    请尝试在 cmd 中输入 d2j-dex2jar classes.dex,而不是输入已经过时的 dex2jar classes.dex 命令。这样做可以使命令更加通用。 - Umesh
    25
    对于那些找不到framework-res.apk的人,可以在这里下载它:链接。请注意,该链接需要翻墙才能访问。 - atulkhatri
    14
    如果没有找到d2j-dex2jar.sh文件,请从此处下载dex2jar:https://dex2jar.googlecode.com/files/dex2jar-0.0.9.15.zip。请注意,不要改变原文意思,只需简化语言并保持准确性。 - Reaz Murshed
    17
    对于卡在步骤2:4的用户:请下载此版本以解决问题:https://sourceforge.net/projects/dex2jar/files/dex2jar-2.0.zip/download 它对我有用。@delive - siriuseteor77
    显示剩余65条评论

    144

    这是备用说明 - 以防上面的说明有人卡住。按照以下步骤进行:

    1. 下载apktool.bat(或Linux版的apktool)和apktool_<version>.jar,从http://ibotpeaches.github.io/Apktool/install/下载。
    2. 将上述jar文件重命名为apktool.jar并将两个文件放在同一个文件夹中

    3. 打开一个dos窗口(cmd.exe),并切换到该文件夹;确认已安装Java环境(对于Linux,请检查所需库的注释)
    4. 输入apktool decode [apk文件]进行解码

      中间结果:资源文件,AndroidManifest.xml

    5. 使用你喜欢的解包程序解压APK文件

      中间结果classes.dex

    6. http://code.google.com/p/dex2jar/downloads/detail?name=dex2jar-0.0.9.15.zip&can=2&q=下载并解压缩dex2jar-0.0.9.15.zip
    7. classes.dex 拖放到 dex2jar.bat 上(或在 DOS 窗口中输入 <path_to>\dex2jar.bat classes.dex;Linux 使用 dex2jar.sh

      中间结果classes_dex2jar.jar

    8. 解压缩 classes_dex2jar.jar(根据使用的反编译器可能是可选的)
    9. 反编译您的类文件(例如,使用 JD-GUIDJ Decompiler

      结果:源代码

    注意:不允许反编译第三方包;本指南仅用于从 APK 文件中恢复个人源代码;最终生成的代码可能会被混淆。


    8
    我也可以补充一点,使用APKTool->dex2jar->JD-GUI这条路线的现代替代方案!来试试名为Jadx的开源APK和DEX反编译器:https://sourceforge.net/projects/jadx/files/ 它还有在线版本:http://www.javadecompilers.com/apk - Andrew Rukin
    2
    任何 APK 文件的反编译都是允许的(也就是合法的)。请参考以下问题链接:https://dev59.com/IWkw5IYBdhLWcg3wwNN5 - Rakete1111
    1
    为什么这些apktool返回smali文件?如何获取java文件? - rminaj
    2
    @AndrewRukin 那个链接重定向到sourceforge的dex2jar页面。 - user202729
    我看不到classes.dex文件 :( - Ontropy
    @Ontropy 重命名 APK 文件后解压缩,您应该在根文件夹中找到 classes.dex 文件。如果没有,请检查是否存在优化的 dex 文件 - 参见 https://www.codeproject.com/Questions/720764/Some-Apk-file-doesnt-have-classes-dex。 - Trinimon

    130

    尽管您可以对APK文件进行反编译,但可能会遇到一个大问题:

    它将不会返回您编写的代码。相反,它将返回编译器内联的任何内容,其中变量具有随机名称并且函数具有随机名称。尝试反编译并将其恢复为您拥有的代码可能需要更长的时间,而重新开始可能更为简单。

    可悲的是,像这样的事情已经毁掉了许多项目。
    对于未来,我强烈建议学习版本控制系统,如CVSSVNGit等,并学会如何备份。


    58

    Play Store上也有一个新的应用程序,可以反编译apk(包括系统应用程序),并在智能手机上查看源代码。它会将文件保存到您的SD卡中,因此您也可以在计算机上查看它。不需要root或其他任何东西。

    只需安装并享受乐趣。我认为这是最简单的反编译应用程序的方法。


    @MidhunVijayakumar,你能否使用这个工具将apk转换为源代码? - Sajeev

    30

    Apktool 是你可以尝试的最好的东西。我用它保存了一些 XML,但老实说我不知道它如何与 .java 代码配合工作。

    我建议你即使只有一个程序员,也要拥有一个代码仓库。我一直在使用 Project Locker 来管理自己的项目。它提供免费的 SVN 和 Git 仓库。


    如果你想从Android应用中提取资源(例如图像),那么你会发现apktool是必不可少的。实际上,这个工具根本没有竞争对手!apktool的在线版本可以在这里找到:www.javadecompilers.com/apktool - Andrew Rukin

    26
    这两篇文章介绍了如何结合使用apktooldex2jar,将一个APK文件转换成可以构建和运行的Eclipse项目。请保留HTML标签。

    http://blog.inyourbits.com/2012/11/extending-existing-android-applications.html

    http://blog.inyourbits.com/2012/12/extending-existing-android-applications.html

    基本上,您需要:
    1. 使用 apktool 将资源文件从apk中提取出来
    2. 使用 dex2jar 获取一个包含Eclipse所喜欢的格式中的类的jar文件。
    3. 创建一个Eclipse项目并将其指向资源文件和新的jar文件
    4. 用zip实用程序打开jar文件并删除现有的资源
    5. 使用 JDGui 打开jar文件以查看源代码
    6. JDGui 中获取所需的源代码,将其放入Eclipse中的一个类中并进行修改
    7. 从jar文件中删除该类(以避免多次定义相同的类)
    8. 运行它。

    2
    我知道这个问题已经有答案了,但我想传递一个信息:有一个在线反编译Android APK的工具http://www.decompileandroid.com/上传本地机器上的APK文件, 等待一些时间, 以zip格式下载源代码。 - Snehal Masne
    2
    听起来不错。而且decompileandroid网站还有你所有源代码的副本!聪明! - DDSports
    一个问题,我已经反编译了一个apk文件,但在jd gui中我不确定是否有真正的Java类,你知道吗,如果一个apk被反编译了,是否存在真正的Java类? - user9049996

    23

    apktool可以使用,您甚至不需要了解密钥库即可提取源代码(有点可怕)。主要缺点是源代码以Smali格式呈现,而不是Java格式。其他文件,如图标和main.xml,都可以完美地通过,并且花时间恢复这些文件可能是值得的。最终,您很可能需要从头开始重写Java代码。

    您可以在此处找到apktool。只需下载apktool和适当的助手(适用于Windows、Linux或Mac OS)。我建议使用诸如7-zip之类的工具进行解压。


    20

    有几种方法可以做到这一点:

    1. Use the "Profile or Debug APK" feature in Android Studio 3.0.

      It allows you to open and explore APKs in Android Studio. Classes are decompiled into smali. Resources are not extracted and things like "Go to Definition", "Find All References" and debugging don't work without the source code (android studio 3.0 canary 9). Some additional smali features might work with smalidea.

      android-studio

      select-file

      code

    2. Use jadx.

      Jadx decompiles the code in a given APK to java source files.

      jdax-img

    3. Use apktool.

      Apktool is a command line tool which extracts resources and decompiles code into smali for a given apk. You can recompile using apktool also. Here's an example of it in action:

      $ apktool d test.apk
      I: Using Apktool 2.2.4 on test.apk
      I: Loading resource table...
      I: Decoding AndroidManifest.xml with resources...
      I: Loading resource table from file: 1.apk
      I: Regular manifest package...
      I: Decoding file-resources...
      I: Decoding values */* XMLs...
      I: Baksmaling classes.dex...
      I: Copying assets and libs...
      I: Copying unknown files...
      I: Copying original files...
      $ apktool b test
      I: Using Apktool 2.2.4 on test
      I: Checking whether sources has changed...
      I: Smaling smali folder into classes.dex...
      I: Checking whether resources has changed...
      I: Building resources...
      I: Building apk file...
      I: Copying unknown files/dir...
      

    我尝试过jadx,但即使是简单的helloworld程序,虽然它将其反编译为java代码,但是尝试在Android Studio中打开该项目并将其重新编译为apk时,由于许多原因(文件重复等),都会失败。是否有任何方法可以创建可编译回apk的java代码? - ransh
    1
    @ransh 我通常使用jadx来阅读代码,然后使用apktool修改代码。apktool不能创建Java代码,但它允许重新编译。 - 0xcaff
    0xcaff,感谢您的澄清。现在这很有意义。因为我试图在Android Studio中编译反编译的Java代码,但一直无法成功。 - ransh

    19

    13
    它列出了类和方法,但没有提供源代码。 - WSS
    你只需将“.apk”更改为“.zip”,即可获取上述文件。 - M. Usman Khan

    9
    以下是在线工具:http://www.javadecompilers.com/apk,它只需一次点击即可完成所有操作:反编译.java文件+资源+xml(在一个.zip文件中),并使用非常好的反编译器(jadx将返回其他编译器在函数内部返回注释的地方的Java代码,如“无法反编译”或某些Android汇编/机器代码)。请注意保留HTML标记。

    是的,这很棒,但它已经将所有函数名称更改为CS1001等。那么如何识别这些函数呢? 还有一件事,我们能直接将这个反编译的apk用作我们的Android Studio项目吗?它会起作用吗? - Zia Ur Rahman
    如果我们不能在我们的应用程序中使用它们的功能,那么我们为什么要反编译某人的apk呢? - Zia Ur Rahman
    @ZiaUrRahman 我不知道。但是在我的情况下,我会反编译代码以分析算法。你是否检查过从该工具反编译的代码是否可以通过Android Studio进行完全自动化的编译 - 还是需要一些“人工处理”? - Kamil Kiełczewski
    1
    我在Android Studio中导入了反编译的项目,但是没有Gradle文件,而且该项目有很多文件,直到我们运行它才能理解。简单地说,它不起作用。我需要使反编译的项目在Android Studio中完全可用,然后获取某些核心功能,并将其用于/嵌入到我的项目中。那么有没有办法可以做到这一点呢? - Zia Ur Rahman
    这个在线工具使用Jadx,任何人都可以下载并在自己的计算机上运行,不必忍受每5秒钟就会闪烁的广告。同时它也会像Jadx一样失败。 - AaA

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