Java中常用的反编译工具

Copyright©stonee

反编译对了解Java语法糖很有帮助
本文没有写与eclipse或者idea相对应的插件,因为本文的目的是为了了解语法糖,而集成开发环境中的反编译插件有时候并不能直观地显示出编译器语法糖的特点

  • 先放上一段源码便于下面的解释
public class tesst{
    public static void main(String[] args) {
        String string = "world";
        switch (string){
            case "hello":
                System.out.println(string);
                break;
            case "world":
                System.out.println(string);
                break;
            default:
                break;
        }
    }
}

javap

javap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码

  • 常用的命令是javap -c E:\Codes\Java\IdeaProjects\testt\tesst.class" 用来输出字节码
public class testt.tesst {
  public testt.tesst();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String world
       2: astore_1
       3: aload_1
       4: astore_2
       5: iconst_m1
       6: istore_3
       7: aload_2
       8: invokevirtual #3                  // Method java/lang/String.hashCode:()I
      11: lookupswitch  { // 2
              99162322: 36
             113318802: 50
               default: 61
          }
      36: aload_2
      37: ldc           #4                  // String hello
      39: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      42: ifeq          61
      45: iconst_0
      46: istore_3
      47: goto          61
      50: aload_2
      51: ldc           #2                  // String world
      53: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      56: ifeq          61
      59: iconst_1
      60: istore_3
      61: iload_3
      62: lookupswitch  { // 2
                     0: 88
                     1: 98
               default: 108
          }
      88: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      91: aload_1
      92: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      95: goto          108
      98: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
     101: aload_1
     102: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     105: goto          108
     108: return
}
  • 默认是javap -package E:\Codes\Java\IdeaProjects\testt\tesst.class" 输出包名
public class testt.tesst {
  public testt.tesst();
  public static void main(java.lang.String[]);
}
  • 可查阅javap --help

Jad

Jad是一款用c++写的针对于Java的反编译工具,相对来说比较好用但是好久没有更新了,不支持Java8的新特性

要先进入jad的安装目录

  • 常用命令

D:\Decompiler>jad.exe E:\Codes\Java\IdeaProjects\testt\tesst.class

之后会在安装目录生成一个jad文件,用文本编辑器打开就可以看到反编译程序了

  • 键入D:\Decompiler>jad.exe 可获得其他命令
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   tesst.java

package testt;

import java.io.PrintStream;

public class tesst
{

    public tesst()
    {
    }

    public static void main(String args[])
    {
        String string = "world";
        String s = string;
        byte byte0 = -1;
        switch(s.hashCode())
        {
        case 99162322: 
            if(s.equals("hello"))
                byte0 = 0;
            break;

        case 113318802: 
            if(s.equals("world"))
                byte0 = 1;
            break;
        }
        switch(byte0)
        {
        case 0: // '\0'
            System.out.println(string);
            break;

        case 1: // '\001'
            System.out.println(string);
            break;
        }
    }
}

Crf

crf是用java写的一款支持java8特性的反编译工具,常用命令如下:

//首先要先进如安装crf的目录中

//反编译stringswitch
D:\Decompiler>cfr-0.144.jar E:\Codes\Java\IdeaProjects\testt\tesst.class --decodestringswitch false --outputdir E://Codes/Java/Class
//反编译lambda
D:\Decompiler>cfr-0.144.jar E:\Codes\Java\IdeaProjects\testt\tesst.class ----decodelambdas false --outputdir E://Codes/Java/Class
//反编译enumswitch
D:\Decompiler>cfr-0.144.jar E:\Codes\Java\IdeaProjects\testt\tesst.class ----decodeenumswitch false --outputdir E://Codes/Java/Class
//反编译finally
D:\Decompiler>cfr-0.144.jar E:\Codes\Java\IdeaProjects\testt\tesst.class ----decodefinally false --outputdir E://Codes/Java/Class
//别的可使用
D:\Decompiler>cfr-0.144.jar --help

//下面是一个栗子:
/*
 * Decompiled with CFR 0.144.
 */
package testt;

import java.io.PrintStream;

public class tesst {
    public static void main(String[] args) {
        String string;
        String string2 = string = "world";
        int n = -1;
        switch (string2.hashCode()) {
            case 99162322: {
                if (!string2.equals("hello")) break;
                n = 0;
                break;
            }
            case 113318802: {
                if (!string2.equals("world")) break;
                n = 1;
            }
        }
        switch (n) {
            case 0: {
                System.out.println(string);
                break;
            }
            case 1: {
                System.out.println(string);
                break;
            }
        }
    }
}
  • 希望每一步都踏踏实实,希望知道的越来越多:)

你可能感兴趣的:(Java成神之路)