如何反编译整个Jar文件?

339

有没有人知道一个可以反编译整个Jar文件而不是单个类的免费反编译器?我有一个处理子类名称如name$1.class name$2.class name.class的问题。


145
记得还有两件事情:1)仅仅提到反编译器就会引起那些自以为是的人出来,对你的动机进行价值判断,尽管他们不知道你计划使用它做什么,所以要小心谁和你交谈。2)高级的Java反编译器可以给你一个很好的代码版本,排版整齐易读,只是缺少注释。它非常出色,可以恢复一个已经丢失源代码和变量名的JAR文件。当然,我们不对内部的JAR文件进行混淆处理。 - Andrew
1
请参阅选择和测试Java反编译器中的备注。 - dma_k
10
每次我需要学习别人如何为Bukkit插件完成某些任务时,都会经常访问这个帖子。那条评论总是让我感到开心,希望可以每次访问时都能点赞它。 - Jane Panda
如果您不想下载任何软件,可以使用简单的在线反编译器。http://www.javadecompilers.com/ - Nick Graham
1
这个不应该被关闭,因为反编译器的游乐场是动态变化的。目前最好的可能是FernFlower。如果你正在寻找一个简单的解决方案,请下载Windup并在你的.jar上运行它的命令行版本。它将使用FernFlower进行反编译,支持Java 8(jad只支持Java 1.3,JavaDecompiler支持Java 1.5 IIRC),如果FernFlower失败,则回退到Procyon。 - Ondra Žižka
显示剩余2条评论
8个回答

367
2023年:splashout评论中建议将Quiltflower重命名为Vineflower,并发布了Vineflower/vineflower反编译器(版本)。
java -jar vineflower.jar -dgs=1 c:\Temp\binary\library.jar c:\Temp\souce

2022更新:QuiltMC/quiltflower是最新的最先进的Java反编译器

Quiltflower是一个现代化的、通用的反编译器,专注于提高代码质量、速度和易用性。
Quiltflower是Fernflower和Forgeflower的一个分支。

改动包括: - 新的语言特性(资源试用、switch表达式、模式匹配等) - 更好的控制流程生成(循环、try-catch、switch等) - 更多的可配置性 - 更好的错误消息 - Javadoc应用 - 多线程 - 优化 - 许多其他杂项特性和修复
最初只是为了与Minecraft的QuiltMC工具链配套使用,Quiltflower迅速扩展为一个旨在创建尽可能准确和清晰代码的通用Java反编译器。
如果名字听起来熟悉,那是因为Quiltflower是Fernflower的分支,Fernflower是由Stiver开发、Jetbrains维护,并成为Intellij IDEA的默认反编译器的(臭名昭著的)反编译器。Fernflower也迅速被许多其他工具采用。
过去一年里,Quiltflower添加了对现代字符串拼接、代码格式化、封闭类、模式匹配、switch表达式、资源试用等特性的支持。Quiltflower还专注于反编译输出代码的质量,并非常重视可读性。

请查看输出示例

Runs nice with jbang

https://github.com/QuiltMC/quiltflower/releases/download/1.8.1/quiltflower-1.8.1.jar

或者:

java -jar quiltflower.jar -dgs=1 c:\Temp\binary\library.jar c:\Temp\binary\Boot.class c:\Temp\source\

2009年:Java反编译器可以很好地处理JAR文件:自0.2.5版本以来,所有文件在JAR文件中都会显示出来。

http://java.decompiler.free.fr/sites/default/screenshots/screenshot1.png

另请参阅“如何反编译Java类文件?”的问题

然而,自2009年底以来,JD-Eclipse似乎没有变化(参见更改)。
因此,它与最新的Eclipse(3.8、4.2+)的集成可能会有问题。

JD-Core正在积极维护。

两者都是(SO用户)Emmanuel Dupuy出色工作的结果。


2018年:一个更现代的选择,在评论中提到David Kennedy AraujoJetBrains/intellij-community/plugins/java-decompiler/engine

Fernflower is the first actually working analytical decompiler for Java and probably for a high-level programming language in general.

java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>

java -jar fernflower.jar -hes=0 -hdc=0 c:\Temp\binary\ -e=c:\Java\rt.jar c:\Temp\source\
请参考如何在IntelliJ IDEA中反编译为Java文件,以获取与最近的IntelliJ IDEA配合使用的命令。
2022年更新:Florian Wendelborn评论中提出了建议。

这个很好用:jdec.app,来自Leonardo Santos


5
Java反编译器可在Windows、Mac和Linux上运行。 - yanokwa
4
@AlexS 不错 :) 下一步:版本控制(http://stackoverflow.com/questions/59561/what-tools-techniques-can-benefit-a-solo-developer)然后是持续集成(https://dev59.com/d3VC5IYBdhLWcg3w-WSs) - VonC
4
使用Java反编译器,您可以打开JAR文件并转到“文件”,然后保存所有源代码。这将把所有的类文件保存成java文件。 =D - Akira Yamamoto
2
请记住,它也会出错。我有一个带有成员变量的类,并将其移动到函数的参数中,破坏了代码的效果。小心,它会找上你的。 - CharlesW
2
JD是一个不错的起点,但无法反编译复杂的代码。 一个好的替代方案是使用https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine。 - David Kennedy
显示剩余12条评论

41

首先,值得记住的是,所有Java归档文件(.jar/.war/等等...)都是基本上只是带有一些添加清单和元数据的花哨的.zip文件。

其次,为了解决这个问题,我个人使用多个工具来处理这个问题的各个方面:

  • Jad + Jadclipse 在IDE中工作时用于反编译.class文件
  • WinRAR,我最喜欢的压缩工具,原生支持Java存档(再次参见第一段)。
  • Beyond Compare,我最喜欢的比较工具,正确配置后可以在任何存档文件之间进行即时比较,包括jar。非常值得一试。

所有上述工具的优点是,我不需要保留任何其他外部工具,因为它们会使我的工作环境混乱。我将来自这些文件的所有内容都可以在我的IDE内部处理或与其他文件进行本地比较。


38

如果您同时拥有bash shell和jad:

JAR=(your jar file name)
unzip -d $JAR.tmp $JAR
pushd $JAR.tmp
for f in `find . -name '*.class'`; do
    jad -d $(dirname $f) -s java -lnc $f
done
popd

我可能有一点点偏差,但它应该更或多或少按照广告所说的方式工作。你最终应该得到包含反编译文件的$JAR.tmp


1
在Ubuntu上使用#!/bin/bash而不是#!/bin/sh,因为默认的Ubuntu shell无法使用pushd命令。 - mossplix
1
我正在使用javap在这个基本的循环结构中,它对我很有效。 - Chris Prince
@mossplix 或使用 /bin/sh(更具可移植性),并使用 cdcd -,对于这个用例来说已经足够了 :-) - ljrk

28

我使用过一个名为(令人沮丧的)"JD: Java反编译器"的工具,取得了合理的成功。

我发现与大多数反编译器相比,它在处理针对Java 5及更高版本编译的类时效果更好。不幸的是,它仍然可能会出现一些问题,而JAD通常可以成功。


我无法下载JD-GUI的Windows或Linux版本。这个问题只出现在我这里吗? - mmdemirbas
@JanusTroelsen,我已经删除了它。谢谢你的通知。让我们保持回答干净 :) - pramodc84

13

类似这样:

jar -xf foo.jar && find . -iname "*.class" | xargs /opt/local/bin/jad -r

也许呢?


1
我已经使用jad有一段时间了,需要一种快速提取和反编译整个jar的方法。谢谢,这对我帮助很大。 - Alper Akture
立即生效 - Joel Wembo

5

将以下内容插入到decompile.jar.sh中

# Usage: decompile.jar.sh some.jar [-d]

# clean target folders
function clean_target {
  rm -rf $unjar $src $jad_log
}

# clean all debug stuff
function clean_stuff {
  rm -rf $unjar $jad_log
}

# the main function
function work {
  jar=$1
  unjar=`basename $jar.unjar`
  src=`basename $jar.src`
  jad_log=jad.log

  clean_target

  unzip -q $jar -d $unjar
  jad -d $src -ff -r -lnc -o -s java $unjar/**/*.class > $jad_log 2>&1

  if [ ! $debug ]; then
    clean_stuff
  fi

  if [ -d $src ] 
    then
      echo "$jar has been decompiled to $src"
    else
      echo "Got some problems check output or run in debug mode"
  fi
}

function usage {
  echo "This script extract and decompile JAR file"
  echo "Usage: $0 some.jar [-d]"
  echo "    where: some.jar is the target to decompile"
  echo "    use -d for debug mode"
}

# check params
if [ -n "$1" ]
  then
    if [ "$2" == "-d" ]; then
      debug=true
      set -x
    fi
    work $1
  else
    usage
fi
  • chmod +x decomplie.jar.sh //可执行
  • ln -s ./decomplie.jar.s /usr/bin/dj

准备就绪,只需输入dj your.jar,您将获得带有源代码的your.jar.src文件夹。使用-d选项进行调试模式。


谢谢,但我不得不在第23行将“jad”更改为“./jad”,并运行“bash decompile.jar.sh foo.jar -d”,因为我不想污染我的bin文件夹。 - Sam
有任何重新编译器吗?可以将Jad文件重新编译成Jar文件吗? - N Jay

1

注意:此解决方案仅适用于 Mac 和 *nix 用户。

我也试图找到 Jad,但没有成功。我的快速解决方案是下载 MacJad,其中包含 jad。一旦你下载了它,你可以在 [where-you-downloaded-macjad]/MacJAD/Contents/Resources/jad 中找到 jad。


0

你需要先解压它,然后使用jad对该目录进行操作。


我认为你不能只针对dir运行它。你必须指定{dir} / ** / * .class - Vihung
解压缩这个jar文件,使用类似"jad {dir}"的命令进行反编译。我刚刚测试了一下,在Windows上无法工作。 - Jaime Hablutzel

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