如何反编译Java

3

我希望能找到一种简单的方法来反编译Java代码。我想检查javac编译器对我的代码所做的转换和修改。有哪些好的产品,它们的优点和缺点是什么。


2
有很多起点吗?http://stackoverflow.com/search?q=decompiler+java - wkl
1
编译器永远不会修改您的代码,它将您的代码转换为Java字节码(存储在.class文件中)。 - Buhake Sindi
2
值得注意的是,编译器进行的优化很少,并且无法给你一个关于JVM在运行时会如何处理它的很好的想法。所有重要的优化都是在JVM中完成的。 - Peter Lawrey
5个回答

5
快速而简单的方法是使用JDK附带的javap工具。
javap -c test
Compiled from "test.java"
public class test extends java.lang.Object{
public test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[])   throws java.lang.Exception;
  Code:
   0:   ldc #2; //String CR_ABC_DEF_GHI
   2:   astore_1
   3:   ldc #3; //String TYPE=Eligibility Only|CLIENT_ID=62|EMPLOYER_ID=0|LOCATION_ID=0|PLAN_ID=all|FREQUENCY=52|FILE=null|FILETYPE=C|PROCESSTOLAUNCH=10|PROCESSTOLAUNCHSTATUS=100|SCHEDULE_ID=29837d692f4c43e786f1097fab7c360c
   5:   astore_2
   6:   ldc #4; //String \|
   8:   astore_3
   9:   ldc #5; //String FILE_NAME_TEMPLATE
   11:  astore  4
   13:  ldc #6; //String FILE
   15:  astore  5
   17:  new #7; //class java/lang/StringBuilder
   20:  dup
   21:  invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   24:  aload_3
   25:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   28:  aload   4
   30:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   33:  ldc #10; //String =
   35:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   38:  ldc #11; //String [^
   40:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   43:  aload_3
   44:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   47:  ldc #12; //String ]*
   49:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   52:  aload_3
   53:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   56:  invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   59:  astore  6
   61:  new #7; //class java/lang/StringBuilder
   64:  dup
   65:  invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   68:  aload_3
   69:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   72:  aload   5
   74:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   77:  ldc #10; //String =
   79:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   82:  ldc #11; //String [^
   84:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   87:  aload_3
   88:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   91:  ldc #12; //String ]*
   93:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   96:  aload_3
   97:  invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   100: invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   103: astore  7
   105: new #7; //class java/lang/StringBuilder
   108: dup
   109: invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   112: aload_3
   113: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   116: aload   4
   118: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   121: ldc #10; //String =
   123: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   126: aload_1
   127: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   130: aload_3
   131: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   134: invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   137: astore  8
   139: aload_2
   140: aload   6
   142: aload   8
   144: invokevirtual   #14; //Method java/lang/String.replaceAll:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
   147: aload   7
   149: aload   8
   151: invokevirtual   #14; //Method java/lang/String.replaceAll:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
   154: astore  9
   156: getstatic   #15; //Field java/lang/System.out:Ljava/io/PrintStream;
   159: new #7; //class java/lang/StringBuilder
   162: dup
   163: invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   166: ldc #16; //String before = 
   168: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   171: aload_2
   172: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   175: invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   178: invokevirtual   #17; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   181: getstatic   #15; //Field java/lang/System.out:Ljava/io/PrintStream;
   184: new #7; //class java/lang/StringBuilder
   187: dup
   188: invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   191: ldc #18; //String pattern1 = 
   193: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   196: aload   6
   198: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   201: invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   204: invokevirtual   #17; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   207: getstatic   #15; //Field java/lang/System.out:Ljava/io/PrintStream;
   210: new #7; //class java/lang/StringBuilder
   213: dup
   214: invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   217: ldc #19; //String pattern2 = 
   219: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   222: aload   7
   224: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   227: invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   230: invokevirtual   #17; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   233: getstatic   #15; //Field java/lang/System.out:Ljava/io/PrintStream;
   236: new #7; //class java/lang/StringBuilder
   239: dup
   240: invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   243: ldc #20; //String replace = 
   245: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   248: aload   8
   250: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   253: invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   256: invokevirtual   #17; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   259: getstatic   #15; //Field java/lang/System.out:Ljava/io/PrintStream;
   262: new #7; //class java/lang/StringBuilder
   265: dup
   266: invokespecial   #8; //Method java/lang/StringBuilder."<init>":()V
   269: ldc #21; //String after = 
   271: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   274: aload   9
   276: invokevirtual   #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   279: invokevirtual   #13; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   282: invokevirtual   #17; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   285: return

}

1
这将让你更好地了解编译器正在做什么。反编译器会尽力将其转换回合理的代码,隐藏很多细节。 - Peter Lawrey

2

1

1

0

我曾经使用过JAD,并且可以证明它的实用性。

但是需要提醒的是,任何反编译的代码很可能都不包含任何注释,如果代码被混淆了,那么反编译也不会有什么作用。它看起来仍然像乱码。


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