反编译一个APK,修改它,然后重新编译

88

我需要修改一个现有的APK文件,更改源代码并重新编译它。

  • 我可以使用dex2jar或apktool反编译它,这很好用
  • 从jar文件中,我可以使用jd-gui获得java源代码
  • 然后我可以修改java文件

但现在我想知道如何重新编译Java文件并将其放回jar文件中!(制作jar文件部分应该很容易,主要问题似乎是如何为Android重新编译Java文件)

我知道另一种方法是使用apktool,然后修改smali文件,但当我们想添加大量代码时,这似乎非常复杂!

我的应用程序是一个基本的HelloWorld,没有混淆。


7
当然,您需要像任何Android开发人员一样使用Android SDK构建Java文件。 - C. K. Young
8个回答

57

感谢Chris Jester-Young,我设法让它工作了!

我认为我成功的方法仅适用于非常简单的项目:

  • 使用Dex2jar获得Jar文件。
  • 使用jd-gui将Jar转换回Java文件。
  • 使用apktool获取Android清单文件和资源文件。

  • 在Eclipse中创建一个具有与旧项目相同设置的新项目(检查清单文件中的所有信息)

  • 创建项目后,我用apktool获取的清单和资源替换所有资源和清单文件。
  • 我将从Jar文件中提取的Java文件粘贴到src文件夹中(遵守包规则)
  • 然后,我按照需要修改这些文件。
  • 所有东西都编译成功了!

/!\请确保您已从设备中删除了旧apk,否则会引发错误,指出apk签名与旧版不同!


11
这在复杂应用程序上行不通(Dex2jar并非完美——一些开发者使用Proguard或类似技术来锁定他们的应用程序)。但对于某些应用程序,它可能有效。 - Ahmad
5
我曾成功地在一个非常庞大的应用程序中使用这种方法,我认为它也可以完美地适用于某些复杂的应用程序。 - Muhammed Refaat
@loveisbug 是的,我试过了,这个应用不是我的,但是我通过这种方式成功反编译了apk文件,但是由于该应用使用了混合技术而非本地编码,因此将其转换为本地编码并不能给我完美的结果,但至少我可以查看我想要查看的类和方法。 - Muhammed Refaat
@MuhammedRefaat 谢谢,我的情况中有许多不可读的变量和函数,我认为它不能直接重新编译。 :( - loveisbug
@loveisbug 是的,我认为这取决于apk的类型而不是大小,祝你解决问题好运。 - Muhammed Refaat
显示剩余5条评论

38

我知道这个问题已经有答案了,但我想传达一个信息,即如何在没有使用dexjar的情况下获取apk的源代码。

有一个在线反编译器适用于Android apk文件:

  1. 从本地机器上传apk文件
  2. 等待片刻
  3. 以zip格式下载源代码
  4. 解压缩zip文件
  5. 检查代码是否能够编译
  6. 随意进行修改

我不知道这个方法有多可靠。

@darkheir 的回答是手动反编译apk的方法。它帮助我们理解apk创建的不同阶段。

这些链接上有很多广告 另一个在线apk反编译器 @Andrew Rukinhttp://www.javadecompilers.com/apk

仍然值得一试。向创作者致敬。


40
“但现在我想知道如何重新编译Java文件并将它们放回到一个jar文件中!” 这是核心问题对吗?上面的回答没有回答这个问题。 - C4d
@IgorLerinc 在我回答这个问题的时候,这个网站上没有广告,我会把它从列表中移除。 - edwin

20

这些答案已经有点过时或不完整。这可能适用于非受保护的APK(没有Proguard),但现在没有人部署未受保护的APK。我能够修改一个(我的)受到很好保护的APK(Proguard,安全检查,检查“黑客工具”,安全检查,检查应用程序是否以调试模式重新打包等)的方法是使用apktool,正如其他人在这里提到的。但没有人解释,你必须再次对应用程序进行签名。

apktool d app.apk
//generates a folder with smali bytecode files. 

//Do something with it.

apktool b [folder name] -o modified.apk
//generates the modified apk.

//and then
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ~/.android/debug.keystore modified.apk androiddebugkey
//signs the app the the debug key (the password is android)

//this apk can be installed on a device.
在我的测试中,原始的发布apk没有记录日志。使用apktool反编译后,我用有日志记录的完整字节码文件替换了没有日志记录的完整字节码文件,并重新编译并签名它,然后我就能够在设备上安装它了。随后,在将应用连接到Android Studio时,我能够看到日志。
在我看来,使用 dex2jar 和 JD-GUI 进行反编译只是为了更好地理解类正在做什么,仅仅是为了阅读而已。但由于所有东西都被混淆了,我不确定您是否可以将这个半成品的Java代码重新编译为一个可工作的apk。如果可以,请让我知道。我认为,唯一的方法就是像本例中提到的那样操作字节码本身。

很棒的解决方案,但现在jarsigner不支持更新的Android签名方案。https://github.com/patrickfav/uber-apk-signer 更适合使用,而不是jarsigner。 - undefined

11
  1. 首先从以下链接下载 dex2jar 工具 http://code.google.com/p/dex2jar/downloads/list

  2. 解压文件并创建 dex2jar 文件夹

  3. 现在选择您的 apk 文件并将其扩展名改为 .zip,然后提取此 zip 文件,您会发现 classes.dex 文件

  4. 现在将 classes.dex 文件放入 dex2jar 文件夹中

  5. 现在打开 cmd 窗口并键入 dex2jar 文件夹的路径

  6. 现在键入命令 dex2jar.bat classes.dex 并按 Enter 键

  7. 现在打开 dex2jar 文件夹,您会找到 classes_dex2jar.jar 文件

  8. 接下来您可以从以下链接下载 java 反编译工具 http://java.decompiler.free.fr/?q=jdgui

  9. 最后一步是在 java 反编译工具中打开 classes_dex2jar.jar 文件,现在您可以看到 apk 代码


6
最后一步,打开Java反编译工具中的classes_dex2jar.jar文件,现在你可以看到apk代码。我该如何从这里开始倒推以便在修改类文件后创建apk文件? - Dario Dias
2
@DarioDias 我认为它可以。 - loveisbug
6
@loveisbug DarioDias 询问如何实现,而不是是否可能。 - Denny

6

我知道这个问题已经有答案了,我不打算在这里给出更好的答案。我只是想分享一下我的经验。

有一次我丢失了代码,但只有 apk 文件。我使用下面的工具对其进行反编译,这让我很开心。

这些工具必须在这种情况下使用,否则是不道德的,甚至有时是非法的(窃取别人的努力)。所以请明智地使用它们。

以下是我最喜欢用于此类操作的工具:

javadecompilers.com

如果您需要从 Google Play 获取 apk 文件,您可以搜索或查看以下网站:

在发布本答案时,我测试了所有链接,对我来说都完美运行。

注意: 在混淆代码的情况下,apk 反编译并不有效。因为 Proguard 会缩小和混淆代码,并将类重命名为无意义的名称,这使得理解代码相当困难。

额外福利:

使用 Proguard 的基本教程


2

dex2jarjd-gui一起使用可以提供所有Java源文件,但它们并不完全相同。它们几乎是等价的.class文件(不是100%)。 因此,如果您想更改apk文件的代码:

  • 使用apktool反编译

  • apktool将为每个具有相同名称的Java文件生成smali(dex的汇编版本)文件。

  • smali易于理解,可在相关文件中进行更改,然后使用相同的apktool重新编译(apktool b Nw.apk <Folder Containing Modified Files>


-2

我知道这个问题已经有答案了,我并不想表现得聪明。我只是想分享一下关于这个主题的另一种方法。

使用apk grail下载应用程序

APK Grail提供该应用程序的免费zip文件。


-3

小心!标志“-f”会删除整个文件夹。 - mrek

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