Java JAD反编译文件是否100%准确

Java JAD反编译文件是否100%准确,java,reverse-engineering,decompiling,Java,Reverse Engineering,Decompiling,JAD反编译文件是否100%准确。我正在反编译一些jar文件以获得源代码,当我试图用这些java文件构建项目时,它没有显示准确的构建。是我做错了,还是反编译的文件与原始文件不完全相同。简短回答:99%的情况下,反编译的代码看起来不像原始代码,但其行为方式应该相同。因此,假设反编译器没有犯任何错误,它在功能上应该是准确的,但在实现上却不准确 详细回答:当Java编译器将源代码转换为字节码时,它会执行某些操作,从而改变代码的外观。我不是Java编译器细节方面的专家,但许多编译器执行的一个简单优化是将

JAD反编译文件是否100%准确。我正在反编译一些jar文件以获得源代码,当我试图用这些java文件构建项目时,它没有显示准确的构建。是我做错了,还是反编译的文件与原始文件不完全相同。

简短回答:99%的情况下,反编译的代码看起来不像原始代码,但其行为方式应该相同。因此,假设反编译器没有犯任何错误,它在功能上应该是准确的,但在实现上却不准确

详细回答:当Java编译器将源代码转换为字节码时,它会执行某些操作,从而改变代码的外观。我不是Java编译器细节方面的专家,但许多编译器执行的一个简单优化是将小方法插入代码中调用它们的位置

例如,假设我们编译以下代码:

public class c
{
   public int add(int a, int b)
   {
      return a + b;
   }

   public static void main(String [] args)
   {
      int i = add(1, 2);
   }
}
由于b仅为一行,并且可以安全地用其内容替换,因此智能编译器可以将main方法更改为:

public static void main(String [] args)
{
   int a = 1, b = 2
   int i = a + b;
}
或者这个:

public static void main(String [] args)
{
   int i = 1 + 2;
}
这样做是因为调用方法的开销比将方法的内容直接放入调用位置的开销更大

我不知道Java编译器在这种情况下会做什么,但它确实会像这样对代码进行更改。它不一定是不准确的,因为它与原始代码做相同的事情。由于编译器不会将这些更改的详细信息保留在.class文件中的任何位置,因此反编译器无法知道优化是否在代码中的任何给定点执行,也无法知道优化是否以这种方式编写

还有许多其他东西可能在转换为字节码后无法保存(例如,变量名和注释)


是的,当您查看反编译代码时,您看到的是.class文件的外观,而不是.java文件的外观。即使它看起来不准确,但应该运行相同的程序。

如果该程序中有更多的私有类。反编译器将以自己的方式转换代码,但如果数量较少,则会显示正确的代码。。如果是xml文件,那么它将完全转换……

源文件可能会被混淆。无论如何,请尝试使用jd guino,它没有注释、局部变量名(如果没有调试)、原始行号、原始编译时常量、原始格式等。这些都是因为它们不在字节码中。while(){}和for(){}的字节码无法清楚区分,反编译器可能会将其中一个替换为另一个(语义保持不变)。某些字节码无法正确地反编译为java(例如,生成的代码,由其他基于VM的语言编译器生成的代码)。此外,编译器生成帮助器方法以使内部类工作()Java编译器本身不会以您描述的方式执行内联。理论上,如果方法是
private
,它可以这样做,但即使这样,它也不会做这样的更改,因为它必须保留类的结构(例如,对于通过反射访问方法的情况).内联是由JIT完成的。是的,我没有仔细研究Java编译器,所以我不确定使用什么作为示例。我决定使用这个示例,因为它很容易解释,而且它强调了对代码结构的更改,即使它不像其他平台那样适用于Java对Java编译器了解得更多的人有一个更好的例子,我很乐意添加它(或更改我对社区wiki的答案)。您将看到的最常见的区别是分支方面的细微变化,例如,您可能会看到
while(a){if(!b)f();}
作者最初编写的
while(a){if(b)continue;f();}
a=b?c:d
作者所写的
if(b)a=c;否则a=d;
。您可能会看到引入了更多中间变量,并内联了一些值。但您永远不应该假设反编译的输出在功能上与原始代码等效。这是预期的,但反编译器并非绝对正确。@MikeStrobel我已将答案更改为社区wiki,正如你们已经证明的那样我对Java编译器的了解还不够,无法写出一个好的答案。请随意改进。这是一个非常模糊的答案,可能是错误的答案。您能提供更多的细节或声明的来源吗?