惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
腾讯CDC
V
V2EX
Martin Fowler
Martin Fowler
A
About on SuperTechFans
大猫的无限游戏
大猫的无限游戏
Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Check Point Blog
博客园 - 【当耐特】
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
K
Kaspersky official blog
Security Latest
Security Latest
H
Help Net Security
博客园_首页
美团技术团队
Spread Privacy
Spread Privacy
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
G
Google Developers Blog
NISL@THU
NISL@THU
爱范儿
爱范儿
I
Intezer
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic
P
Privacy International News Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Security @ Cisco Blogs
Schneier on Security
Schneier on Security
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
V
Vulnerabilities – Threatpost
W
WeLiveSecurity
P
Palo Alto Networks Blog
G
GRAHAM CLULEY
Hacker News: Ask HN
Hacker News: Ask HN
I
InfoQ
The Cloudflare Blog
F
Full Disclosure
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
N
Netflix TechBlog - Medium

Java技术经验分享

生产故障处理SOP分享 | Java技术经验分享 系统稳定性建设实践总结【转载】 | Java技术经验分享 valine访问leancloud国际版异常,评论失效修复 | Java技术经验分享 匆匆忙忙的2021 | Java技术经验分享 聊一下换工作 | Java技术经验分享 IoT系列(2):WIFI设备常见配网方案介绍 | Java技术经验分享 IoT系列(1):什么是物联网 | Java技术经验分享 Java8特性2 - StreamApi | Java技术经验分享 Java8特性1 - lambda表达式&函数式接口 | Java技术经验分享 设计模式(5)-适配器模式 | Java技术经验分享 设计模式(4)-建造者模式 | Java技术经验分享 设计模式(3)-原型模式与浅拷贝和深拷贝 | Java技术经验分享 设计模式(2)-工厂模式图文介绍 | Java技术经验分享 设计模式(1)-带你了解3类8种单例模式 | Java技术经验分享 Java时间处理5---Java8中时区相关类库介绍 | Java技术经验分享 Java时间处理4---Java8中LocalDate、LocalTime、LocalDateTime介绍 | Java技术经验分享 Java时间处理3---Java8中Instant、Duration、Period、Clock介绍 | Java技术经验分享 一些有意思的问答 | Java技术经验分享 Nacos系列博客说明 | Java技术经验分享 菜鸡程序员的2019年度总结 | Java技术经验分享 Java中“附近的人”实现方案讨论及代码实现 | Java技术经验分享 Java时间处理2----时区TimeZone类方法探究(Java8以前) | Java技术经验分享 Java时间处理1----Date和Calendar方法探究(Java8以前) | Java技术经验分享 FastJson中JSONString、JavaBean、JSONObject、JSONArray的转换关系及API示例 | Java技术经验分享 2019.11软考软件设计师归来心得体会及复习备考指南 | Java技术经验分享 你还没用过“约定式提交”吗?那你赶紧来补补知识吧 | Java技术经验分享 教你如何看懂UML中的类图及类图中的关系 | Java技术经验分享 设计模式总览 | Java技术经验分享 萌新入门Github请看这里,学不会远程教 | Java技术经验分享 Hexo的工作原理探究 | Java技术经验分享 Hexo-theme-butterfly修改调整记录教程 | Java技术经验分享 排序8:基数排序 | Java技术经验分享 排序7:归并排序 | Java技术经验分享 排序6:快速排序 | Java技术经验分享 排序5:冒泡排序 | Java技术经验分享 排序4:堆排序 | Java技术经验分享 排序3:选择排序 | Java技术经验分享 排序2:希尔排序 | Java技术经验分享 排序1:直接插入排序 | Java技术经验分享 推荐一款博客一文多发的良心工具OpenWrite | Java技术经验分享 近期学习计划 | Java技术经验分享 Nacos(九):Nacos集群部署和遇到的问题 | Java技术经验分享 Nacos(八):Nacos持久化 | Java技术经验分享 Nacos(七):Nacos共享配置 | Java技术经验分享 Nacos(六):多环境下如何“管理”及“隔离”配置和服务 | Java技术经验分享 Nacos(五):多环境下如何“读取”Nacos中相应的配置 | Java技术经验分享 Nacos(四):SpringCloud项目中接入Nacos作为配置中心 | Java技术经验分享 Nacos(三):Nacos与OpenFeign的对接使用 | Java技术经验分享 Nacos(二):SpringCloud项目中接入Nacos作为注册中心 | Java技术经验分享 Nacos(一):Nacos介绍 | Java技术经验分享 20190719小组分享 | Java技术经验分享 Java中equals和HashCode方法的分析 | Java技术经验分享 Java中==和equals方法的分析 | Java技术经验分享 Java中的自动拆装箱、装箱缓存 | Java技术经验分享 About-blog | Java技术经验分享 finalize()的生命周期(执行过程) | Java技术经验分享 Java关键字之final、finally与finalize方法 | Java技术经验分享 Java中重写、重载 | Java技术经验分享 Java中面向对象的三大特征:继承、封装、多态 | Java技术经验分享 DockerFile介绍 | Java技术经验分享 Docker环境下安装Gitlab | Java技术经验分享 Docker中私有仓库的搭建流程 | Java技术经验分享 Centos7下两种方式安装Docker-CE | Java技术经验分享 Vert.x创建一个Http服务 | Java技术经验分享 Vert.x创建TCP服务端及客户端 | Java技术经验分享 Vert.x Core(二)- Event Bus(事件总线) | Java技术经验分享 Vert.x-Core(一)- 基础篇 | Java技术经验分享 SpringBoot项目中实现国际化 | Java技术经验分享 Vert.x介绍 | Java技术经验分享 毕设选题项目本地运行环境搭建教程 | Java技术经验分享 Jupyter Notebooks的安装和使用介绍 | Java技术经验分享 算法笔试题:1元,5元,10元,20元,50元、100元面值人民币组合给定x元的问题 | Java技术经验分享 Quartz学习总结 | Java技术经验分享 SpringBoot2.x集成Redis | Java技术经验分享 SpringBoot2.x集成MongoDB | Java技术经验分享 [SpringCloud学习] - 浅谈微服务架构 | Java技术经验分享 基于hexo和coding免费搭建个人博客网站 | Java技术经验分享 Hello World | Java技术经验分享
Java中的编译、反编译和反编译工具全家桶分享 | Java技术经验分享
文章作者: LarsCheng · 2019-05-30 · via Java技术经验分享

前言

本文介绍到的反编译工具下载地址:反编译工具全家桶 , 提取码:oxor

编程语言

编程语言分为低级语言和高级语言

1
2
3
4
5
6
graph LR
编程语言-->低级语言
编程语言-->高级语言
低级语言-->机器语言
低级语言-->汇编语言
高级语言-->C/C++/Java/Python....

最早的程序员都是用机器语言在写代码,那时候应该不叫代码,叫写十六进制串,这样的编程十分复杂不方便而且出错率高

后来有一个偷懒的程序员把机器语言中一组一组通用的十六进制用助记符来代替,这种通过助记符的方式被称作汇编语言,用助记符和部分机器语编写程序,最终执行前让汇编器将助记符转换成机器语言。

然鹅,无论是机器语言还是汇编语言,后来的程序员觉得还是很麻烦,于是又有几个偷懒的程序员他们先后创造了c、c++、java、python…

编译

程序员编程是通过高级语言,而计算机执行程序只认识机器语言,那么将高级语言翻译成机器语言的过程就叫做编译。负责执行这一过程的工具叫做编译器

举个例子:

Java语言属于高级语言,计算机不认识

.class文件属于编译后的Java虚拟机认识的字节码文件

Java文件通过Java语言中的编译器javac编译后生成.class字节码文件

说明:字节码并不是机器语言,要想让机器能够执行,还需要把字节码翻译成机器指令。这个过程是Java虚拟机做的,这个过程也叫编译。是更深层次的编译。

反编译

反编译当然就是编译的逆向操作了,将机器认识的机器语言转换成程序员认识的高级语言。

举个例子:
Java种将.class文件转换成Java文件,这一过程就是反编译。

Java中常用的反编译工具

javap

javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码。它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。

用法:javap <options> <classes>

javap命令算是java自己原装的反编译工具,但是他反编译后的代码阅读性不太好,我们也可以用其他方式进行反编译。

JD-GUI

JD-GUI是一个独立的图形实用程序,支持Windows、Linux和苹果Mac Os三个平台,可对“.class”文件进行反编译。可以使用JD-GUI浏览重建的源代码,以便即时访问方法和字段。

jd-dui官方示意图

JD-GUI在1.4.0版本后停止更新了很久,当时的版本对于Java1.7以后的代码兼容性很差,不过最近JD-GUI的恢复更新,并兼容Java9
JD-GUI现在最新的版本是1.5.1,下载jd-gui-1.5.1.jar直接双击执行即可。

github地址

CFR

在JD-GUI断更期间,CFR就被大家广泛使用了。

CFR will decompile modern Java features - up to and including much of Java 9, 10, 12 and beyond, but is written entirely in Java 6, so will work anywhere!

作者表示,CFR可以反编译目前Java 9,10,12及更高版本的大部分功能,但完全用Java 6编写,因此可以在任何地方使用!

CFR的使用也是十分方便,直接下载jar包,通过java -jar执行即可,如下:

java -jar cfr-0.144.jar Demo.class  

最新jar包下载和其他参数使用可参考CFR官网

Procyon

Procyon就很有趣了,它的作者和CFR作者就职同一公司,他们俩在进行一场友谊赛,看看谁能提供更好的反编译器。

Procyon-Decompiler支持JDK1.8类的反编译,并且支持:字符串的Switch、枚举声明方面、注解方面、匿名类、内部类、Java8新接口规范、Java8 Lambda表达式、Java8 方法传递等。

Procyon和CFR的运行方式相同,如下:

java -jar procyon-decompiler-0.5.30.jar Demo.class

最新jar包下载和其他参数使用可参考Procyon地址

Procyon拥有一款第三方的GUI:luyten

如果你习惯像JD-GUI那样操作方便的GUI的话,你可以选择使用Luyten,它是基于Procyon的一款反编译工具,推荐使用哦~
Luyten官方网址

Luyten官方示意图

Fernflower

Fernflower相信经常使用IDEA的同学应该很眼熟叭,他是IDEA自带的反编译工具,我们通过IDEA看到的.class文件内容都是通过Fernflower反编译后的。IDEA中效果如下:

Fernflower.jar下载地址,也可以拉取官方的项目自己在本地进行gradle构建

下好fernflower.jar后也准备好需要编译的jar包。

使用命令行 java -jar fernflower.jar <目标>.jar <文件夹名>/

java -jar fernflower.jar Demo.jar demo/

编译成功后demo文件夹下是一个<文件名>.jar。

可以看到比刚才的目标jar包小一些,解压此jar包就可以查看源码了!

Fernflower github地址

bytecode-viewer(逆向必备!!!)

bytecode-viewer(字节码查看器)一款轻量级的Java字节码查看器,它可以反编译jar包,.class文件、Android APK,并且支持多种反编译器

你可以用CFR、Procyon、Fernflower等同时编译同一个.class文件,并进行结果查看和对比。如下:

是不是很方便呐,github地址 快去下载试试吧。

在线反编译

Java decompiler online

JAVA反向工程网

ps:
部分官网和仓库需要翻墙才可以下载,我这边已经为大家准备好了反编译工具全家桶 , 提取码:oxor

总结

了解编译和反编译的基本概念后,其实反编译可以使我们更好的了解Java代码真实的面目,Java中有很多的语法糖,通过反编译可以很好的了解和学习这些语法糖的实现原理。