
反编译的历程与编译恰好相反,就是将已编译好的编程言语复原到未编译的状况,也就是找出程序言语的源代码。就是将机械看得懂的言语转换成程序员能够看得懂的言语。Java言语中的反编译平常指将class文件转换成java文件。
Java经常运用反编译东西
本文重要引见4个Java的反编译东西:javap、jad和cfr以及可视化反编译东西JD-GUI
JAVAP
javap是jdk自带的一个东西,能够对代码反编译,也能够检察java编译器生成的字节码。javap和其他两个反编译东西最大的区别是他生成的文件并非java文件,也不像其他两个东西生成代码那样更轻易明白。拿一段简朴的代码举例,如我们想剖析Java 7中的switch是怎样支撑String的,我们先有以下能够编译经由过程的源代码:
public class switchDemoString { public static void main(String[] args) { String str = "world"; switch (str) { case "hello": System.out.println("hello"); break; case "world": System.out.println("world"); break; default: break; } } }
实行以下两个敕令:
javac Decompilation.java javap -c Decompilation.class
生成代码以下:
Compiled from "Decompilation.java" public class Decompilation { public Decompilation(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #16 // String world 2: astore_1 3: aload_1 4: dup 5: astore_2 6: invokevirtual #18 // Method java/lang/String.hashCode:()I 9: lookupswitch { // 2 99162322: 36 113318802: 48 default: 82 } 36: aload_2 37: ldc #24 // String hello 39: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 42: ifne 60 45: goto 82 48: aload_2 49: ldc #16 // String world 51: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 54: ifne 71 57: goto 82 60: getstatic #30 // Field java/lang/System.out:Ljava/io/PrintStream; 63: ldc #24 // String hello 65: invokevirtual #36 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 68: goto 82 71: getstatic #30 // Field java/lang/System.out:Ljava/io/PrintStream; 74: ldc #16 // String world 76: invokevirtual #36 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 79: goto 82 82: return }
javap并没有将字节码反编译成java文件,而是生成了一种我们能够看得懂字节码。实在javap生成的文件仍然是字节码,只是程序员能够轻微看得懂一些。假如你对字节码有所控制,照样能够看得懂以上的代码的。实在就是把String转成hashcode,然后举行比较。
JAD
JAD是一个比较不错的反编译东西,只需下载一个实行东西,就能够完成对class文件的反编译了。照样上面的源代码,运用jad反编译后内容以下:
敕令:jad.exe Decompilation.class 会生成一个Decompilation.jad的文件
JAD反编译的效果以下:
// 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: Decompilation.java package com.yveshe; import java.io.PrintStream; public class Decompilation { public Decompilation() { } public static void main(String args[]) { String str = "world"; String s; switch((s = str).hashCode()) { default: break; case 99162322: if(s.equals("hello")) System.out.println("hello"); break; case 113318802: if(s.equals("world")) System.out.println("world"); break; } } }
看上面的代码这不就是规范的java的源代码么。这个就很清晰的能够看到本来字符串的switch是经由过程equals()和hashCode()方法来完成的。
CFR
JAD很好用,然则无法的是很久没更新了,所以只能用一款新的东西替换他,CFR是一个不错的挑选,比拟JAD来讲,他的语法可能会轻微庞杂一些,然则幸亏他能够用.
CFR将反编译当代Java特征–Java 8 lambdas(Java和更早版本中的Java beta 103),已反编译Java 7 String,但CFR是完整用Java 6编写的.
发起人人手动经由过程javac Decompilation.java敕令来编译生成Decompilation.class文件,再做测试.
胜利的反编译效果以下:
/* * Decompiled with CFR 0_125. */ package com.yveshe; import java.io.PrintStream; public class Decompilation { public static void main(String[] args) { String str; String s = str = "world"; switch (s.hashCode()) { default: { break; } case 99162322: { if (!s.equals("hello")) break; System.out.println("hello"); break; } case 113318802: { if (!s.equals("world")) break; System.out.println("world"); } } } }
比拟Jad来讲,CFR有许多参数,照样方才的代码,假如我们运用以下敕令,输出效果就会差别:
E:\CRF>java -jar cfr_0_125.jar Decompilation.class
/* * Decompiled with CFR 0_125. */ package com.yveshe; import java.io.PrintStream; public class Decompilation { public static void main(String[] args) { String str; String s = str = "world"; switch (s.hashCode()) { default: { break; } case 99162322: { if (!s.equals("hello")) break; System.out.println("hello"); break; } case 113318802: { if (!s.equals("world")) break; System.out.println("world"); } } } }
--decodestringswitch示意关于switch支撑string的细节举行解码。
相似的另有--decodeenumswitch、--decodefinally、--decodelambdas等。
--decodelambdas能够对lambda表达式举行反编译。
JD-GUI
JD-GUI 是一个用 C++ 开发的 Java反编译东西,由 Pavel Kouznetsov开发,支撑Windows、Linux和苹果Mac Os三个平台。而且供应了Eclipse平台下的插件JD-Eclipse。JD-GUI 基于GPLv3开源协定,对个人运用是完整免费的。JD-GUI重要的是供应了可视化操纵,直接拖拽文件到窗口既可,效果图以下
JadClipse
在Eclipse中装置Jad插件,注重这里是装置的是Jad插件不是Jd插件~
所须要资本: net.sf.jadclipse_3.3.0.jar插件jar和JAD.exe反编译软件(在文末有下载地点)
JadClipse下载地点在官网下载插件的jar包,然后将jar包放到eclipse的plugins目录下;在翻开Eclipse,Eclipse->Window->Preferences->Java,此时你会发明会比本来多了一个JadClipse的选项以下图设置JadClipse:
基础设置终了后,我们能够设置一下class文件的默许翻开方式:
Eclipse->Window->Preferences->General->Editors->File Associations 我们能够看到class文件的翻开方式有两个,这里设置JadClipse和Eclipse自带的Class File Viewer,而JadClipse是默许的。
悉数设置完成,下面我们能够检察源码了,挑选须要检察的类,按F3即可检察源码.假如JadClipse不是默许设置,设置成默许设置既可.
更多java学问请关注java基础教程栏目。
以上就是java怎样举行反编译的细致内容,更多请关注ki4网别的相干文章!