java 反编译class文件_用Java实现JVM第三章《解析class文件》

3daa94ec21b51f4fe82ef0cc7fc7028a.png

解析class文件

案例介绍

本案例主要介绍通过java代码从class文件中解析;class文件、常量池、属性表;

作为类(或者接口)信息的载体,每个class文件都完整地定义了一个类。为了使java程序可以“编写一次,处处运行”,Java虚拟机规范对class文件格式进行了严格的规定。但是另外一方面,对于从哪里加载class文件,给了足够多的自由。Java虚拟机实现可以从文件系统读取和从JAR(或ZIP)压缩包中提取clss文件。除此之外,也可以通过网络下载、从数据库加载,甚至是在运行中直接生成class文件。Java虚拟机规范中所指的class文件,并非特指位于磁盘中的.class文件,而是泛指任何格式符号规范的class数据。

环境准备

  1. jdk 1.8.0
  2. IntelliJ IDEA Community Edition 2018.3.1 x64

配置信息

  1. 配置位置:Run/Debug Configurations -> program arguments
  2. 配置内容:-Xjre "C:Program FilesJavajdk1.8.0_161jre" java.lang.String

代码示例

https://github.com/fuzhengwei/itstack-demo-jvm/tree/master/itstack-demo-jvm-03

itstack-demo-jvm-03├── pom.xml└── src └── main │ └── java │ └── org.itstack.demo.jvm │ ├── classfile │ │ ├── attributes {BootstrapMethods/Code/ConstantValue...} │ │ ├── constantpool {CONSTANT_TAG_CLASS/CONSTANT_TAG_FIELDREF/CONSTANT_TAG_METHODREF...} │ │ ├── ClassFile.java │ │ ├── ClassReader.java │ │ └── MemberInfo.java  │ ├── classpath │ │ ├── impl │ │ │ ├── CompositeEntry.java │ │ │ ├── DirEntry.java  │ │ │ ├── WildcardEntry.java  │ │ │ └── ZipEntry.java  │ │ ├── Classpath.java │ │ └── Entry.java  │ ├── Cmd.java │ └── Main.java └── test └── java └── org.itstack.demo.test └── HelloWorld.java

代码篇幅较长,不一一列举

AttributeInfo.java

package org.itstack.demo.jvm.classfile.attributes;import org.itstack.demo.jvm.classfile.ClassReader;import org.itstack.demo.jvm.classfile.attributes.impl.*;import org.itstack.demo.jvm.classfile.constantpool.ConstantPool;/** * http://www.itstack.org * create by fuzhengwei on 2019/4/26 */public interface AttributeInfo { void readInfo(ClassReader reader); static AttributeInfo[] readAttributes(ClassReader reader, ConstantPool constantPool) { int attributesCount = reader.readU2ToInt(); AttributeInfo[] attributes = new AttributeInfo[attributesCount]; for (int i = 0; i < attributesCount; i++) { attributes[i] = readAttribute(reader, constantPool); } return attributes; } static AttributeInfo readAttribute(ClassReader reader, ConstantPool constantPool) { int attrNameIdx = reader.readU2ToInt(); String attrName = constantPool.getUTF8(attrNameIdx); int attrLen = reader.readU4ToInt(); AttributeInfo attrInfo = newAttributeInfo(attrName, attrLen, constantPool); attrInfo.readInfo(reader); return attrInfo; } static AttributeInfo newAttributeInfo(String attrName, int attrLen, ConstantPool constantPool) { switch (attrName) { case "BootstrapMethods": return new BootstrapMethodsAttribute(); case "Code": return new CodeAttribute(constantPool); case "ConstantValue": return new ConstantValueAttribute(); case "Deprecated": return new DeprecatedAttribute(); case "EnclosingMethod": return new EnclosingMethodAttribute(constantPool); case "Exceptions": return new ExceptionsAttribute(); case "InnerClasses": return new InnerClassesAttribute(); case "LineNumberTable": return new LineNumberTableAttribute(); case "LocalVariableTable": return new LocalVariableTableAttribute(); case "LocalVariableTypeTable": return new LocalVariableTypeTableAttribute(); // case "MethodParameters": // case "RuntimeInvisibleAnnotations": // case "RuntimeInvisibleParameterAnnotations": // case "RuntimeInvisibleTypeAnnotations": // case "RuntimeVisibleAnnotations": // case "RuntimeVisibleParameterAnnotations": // case "RuntimeVisibleTypeAnnotations": case "Signature": return new SignatureAttribute(constantPool); case "SourceFile": return new SourceFileAttribute(constantPool); // case "SourceDebugExtension": // case "StackMapTable": case "Synthetic": return new SyntheticAttribute(); default: return new UnparsedAttribute(attrName, attrLen); } }}

ConstantInfo.java

package org.itstack.demo.jvm.classfile.constantpool;import org.itstack.demo.jvm.classfile.ClassReader;import org.itstack.demo.jvm.classfile.constantpool.impl.*;/** * http://www.itstack.org * create by fuzhengwei on 2019/4/26 */public interface ConstantInfo { int CONSTANT_TAG_CLASS = 7; int CONSTANT_TAG_FIELDREF = 9; int CONSTANT_TAG_METHODREF = 10; int CONSTANT_TAG_INTERFACEMETHODREF = 11; int CONSTANT_TAG_STRING = 8; int CONSTANT_TAG_INTEGER = 3; int CONSTANT_TAG_FLOAT = 4; int CONSTANT_TAG_LONG = 5; int CONSTANT_TAG_DOUBLE = 6; int CONSTANT_TAG_NAMEANDTYPE = 12; int CONSTANT_TAG_UTF8 = 1; int CONSTANT_TAG_METHODHANDLE = 15; int CONSTANT_TAG_METHODTYPE = 16; int CONSTANT_TAG_INVOKEDYNAMIC = 18; void readInfo(ClassReader reader); int tag();  static ConstantInfo readConstantInfo(ClassReader reader, ConstantPool constantPool) { int tag = reader.readU1ToInt(); ConstantInfo constantInfo = newConstantInfo(tag, constantPool); constantInfo.readInfo(reader); return constantInfo; } static ConstantInfo newConstantInfo(int tag, ConstantPool constantPool) { switch (tag) { case CONSTANT_TAG_INTEGER: return new ConstantIntegerInfo(); case CONSTANT_TAG_FLOAT: return new ConstantFloatInfo(); case CONSTANT_TAG_LONG: return new ConstantLongInfo(); case CONSTANT_TAG_DOUBLE: return new ConstantDoubleInfo(); case CONSTANT_TAG_UTF8: return new ConstantUtf8Info(); case CONSTANT_TAG_STRING: return new ConstantStringInfo(constantPool); case CONSTANT_TAG_CLASS: return new ConstantClassInfo(constantPool); case CONSTANT_TAG_FIELDREF: return new ConstantFieldRefInfo(constantPool); case CONSTANT_TAG_METHODREF: return new ConstantMethodRefInfo(constantPool); case CONSTANT_TAG_INTERFACEMETHODREF: return new ConstantInterfaceMethodRefInfo(constantPool); case CONSTANT_TAG_NAMEANDTYPE: return new ConstantNameAndTypeInfo(); case CONSTANT_TAG_METHODTYPE: return new ConstantMethodTypeInfo(); case CONSTANT_TAG_METHODHANDLE: return new ConstantMethodHandleInfo(); case CONSTANT_TAG_INVOKEDYNAMIC: return new ConstantInvokeDynamicInfo(); default: throw new ClassFormatError("constant pool tag"); } }}

ClassFile.java

package org.itstack.demo.jvm.classfile;import org.itstack.demo.jvm.classfile.attributes.AttributeInfo;import org.itstack.demo.jvm.classfile.constantpool.ConstantPool;/** * http://www.itstack.org * create by fuzhengwei on 2019/4/26 */public class ClassFile { private int minorVersion; private int majorVersion; private ConstantPool constantPool; private int accessFlags; private int thisClassIdx; private int supperClassIdx; private int[] interfaces; private MemberInfo[] fields; private MemberInfo[] methods; private AttributeInfo[] attributes; public ClassFile(byte[] classData) { ClassReader reader = new ClassReader(classData); this.readAndCheckMagic(reader); this.readAndCheckVersion(reader); this.constantPool = this.readConstantPool(reader); this.accessFlags = reader.readU2ToInt(); this.thisClassIdx = reader.readU2ToInt(); this.supperClassIdx = reader.readU2ToInt(); this.interfaces = reader.readUInt16s(); this.fields = MemberInfo.readMembers(reader, constantPool); this.methods = MemberInfo.readMembers(reader, constantPool); this.attributes = AttributeInfo.readAttributes(reader, constantPool); } private void readAndCheckMagic(ClassReader reader) { String magic = reader.readU4ToHexStr(); if (!"cafebabe".equals(magic)) { throw new ClassFormatError("magic!"); } } private void readAndCheckVersion(ClassReader reader) { this.minorVersion = reader.readU2ToInt(); this.majorVersion = reader.readU2ToInt(); switch (this.majorVersion) { case 45: return; case 46: case 47: case 48: case 49: case 50: case 51: case 52: if (this.minorVersion == 0) return; } throw new UnsupportedClassVersionError(); } private ConstantPool readConstantPool(ClassReader reader) { return new ConstantPool(reader); } public int minorVersion(){ return this.minorVersion; } public int majorVersion(){ return this.majorVersion; } public ConstantPool constantPool(){ return this.constantPool; } public int accessFlags() { return this.accessFlags; } public MemberInfo[] fields() { return this.fields; } public MemberInfo[] methods() { return this.methods; } public String className() { return this.constantPool.getClassName(this.thisClassIdx); } public String superClassName() { if (this.supperClassIdx <= 0) return ""; return this.constantPool.getClassName(this.supperClassIdx); } public String[] interfaceNames() { String[] interfaceNames = new String[this.interfaces.length]; for (int i = 0; i < this.interfaces.length; i++) { interfaceNames[i] = this.constantPool.getClassName(interfaces[i]); } return interfaceNames; }}

ClassReader.java

package org.itstack.demo.jvm.classfile;import java.math.BigInteger;/** * http://www.itstack.org * create by fuzhengwei on 2019/5/13 * 

* java虚拟机定义了u1、u2、u4三种数据类型来表示;1字节、2字节、4字节,无符号整数。 * 在如下实现中,用增位方式表示无符号类型: * u1、u2可以用int类型存储,因为int类型是4字节 * u4 需要用long类型存储,因为long类型是8字节 */public class ClassReader { private byte[] data; public ClassReader(byte[] data) { this.data = data; } //u1 public int readUint8() { byte[] val = readByte(1); return byte2int(val); } //u2 public int readUint16() { byte[] val = readByte(2); return byte2int(val); } //u4 public long readUint32() { byte[] val = readByte(4); String str_hex = new BigInteger(1, val).toString(16); return Long.parseLong(str_hex, 16); } public float readUint64TFloat() { byte[] val = readByte(8); return new BigInteger(1, val).floatValue(); } public long readUint64TLong() { byte[] val = readByte(8); return new BigInteger(1, val).longValue(); } public double readUint64TDouble() { byte[] val = readByte(8); return new BigInteger(1, val).doubleValue(); } public int[] readUint16s() { int n = this.readUint16(); int[] s = new int[n]; for (int i = 0; i < n; i++) { s[i] = this.readUint16(); } return s; } public byte[] readBytes(int n) { return readByte(n); } private byte[] readByte(int length) { byte[] copy = new byte[length]; System.arraycopy(data, 0, copy, 0, length); System.arraycopy(data, length, data, 0, data.length - length); return copy; } private int byte2int(byte[] val) { String str_hex = new BigInteger(1, val).toString(16); return Integer.parseInt(str_hex, 16); }}

MemberInfo.java

package org.itstack.demo.jvm.classfile;import org.itstack.demo.jvm.classfile.attributes.AttributeInfo;import org.itstack.demo.jvm.classfile.attributes.impl.CodeAttribute;import org.itstack.demo.jvm.classfile.attributes.impl.ConstantValueAttribute;import org.itstack.demo.jvm.classfile.constantpool.ConstantPool;/** * http://www.itstack.org * create by fuzhengwei on 2019/4/26 */public class MemberInfo { private ConstantPool constantPool; private int accessFlags; private int nameIdx; private int descriptorIdx; private AttributeInfo[] attributes; public MemberInfo(ClassReader reader, ConstantPool constantPool) { this.constantPool = constantPool; this.accessFlags = reader.readU2ToInt(); this.nameIdx = reader.readU2ToInt(); this.descriptorIdx = reader.readU2ToInt(); this.attributes = AttributeInfo.readAttributes(reader, constantPool); } public static MemberInfo[] readMembers(ClassReader reader, ConstantPool constantPool) { int fieldCount = reader.readU2ToInt(); MemberInfo[] fields = new MemberInfo[fieldCount]; for (int i = 0; i < fieldCount; i++) { fields[i] = new MemberInfo(reader, constantPool); } return fields; } public int accessFlags() { return this.accessFlags; } public String name() { return this.constantPool.getUTF8(this.nameIdx); } public String descriptor() { return this.constantPool.getUTF8(this.descriptorIdx); } public CodeAttribute codeAttribute() { for (AttributeInfo attrInfo : attributes) { if (attrInfo instanceof CodeAttribute) return (CodeAttribute) attrInfo; } return null; } public ConstantValueAttribute ConstantValueAttribute() { for (AttributeInfo attrInfo : attributes) { if (attrInfo instanceof ConstantValueAttribute) return (ConstantValueAttribute) attrInfo; } return null; }}

Main.java

package org.itstack.demo.jvm;import org.itstack.demo.jvm.classfile.ClassFile;import org.itstack.demo.jvm.classfile.MemberInfo;import org.itstack.demo.jvm.classpath.Classpath;import java.util.Arrays;/** * http://www.itstack.org * create by fuzhengwei on 2019/4/24 */public class Main { public static void main(String[] args) { Cmd cmd = Cmd.parse(args); if (!cmd.ok || cmd.helpFlag) { System.out.println("Usage:  [-options] class [args...]"); return; } if (cmd.versionFlag) { //注意案例测试都是基于1.8,另外jdk1.9以后使用模块化没有rt.jar System.out.println("java version "1.8.0""); return; } startJVM(cmd); } private static void startJVM(Cmd cmd) { Classpath classpath = new Classpath(cmd.jre, cmd.classpath); System.out.printf("classpath:%s class:%s args:%s

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512901.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解放人与设备距离,5G时代的远程操控该如何完成

物联网这个概念早在十多年前便已提出&#xff0c;其主要依托于移动通讯网络来实现其功能的传输。在过去物联网领域的一些设备控制场景中&#xff0c;我们或多或少都见到过远程控制技术的身影&#xff0c;但受限于当时的网络条件和技术场景&#xff0c;大部分应用都属于对设备的…

Spark 大数据处理最佳实践

开源大数据社区 & 阿里云 EMR 系列直播 第十一期 主题&#xff1a;Spark 大数据处理最佳实践 讲师&#xff1a;简锋&#xff0c;阿里云 EMR 数据开发平台 负责人 内容框架&#xff1a; 大数据概览如何摆脱技术小白Spark SQL 学习框架EMR Studio 上的大数据最佳实践 直播…

CNCF TOC 委员张磊:不断演进的云原生给我们带来了什么?

简介&#xff1a; 任何一种云原生技术&#xff0c;它不再是某种能力的弥补&#xff0c;而是更多地将云的能力以某种方式更简单、更高效地透出给我的应用去使用。无论是容器、K8s 还是 Service Mesh&#xff0c;他们都是在不同的环节帮助应用本身能够更好地去使用云服务。 作者…

php url传递参数_互联网系统(APP、网站等)通信基石——会话(PHP版)

一、会话概述1.1、技术背景互联网通信中采用的Http协议(建立TCP连接->Http请求->Http应答->断开TCP连接)本身是无状态的&#xff0c;即Http各请求之间是相互独立、互不相关的&#xff0c;而大量应用需要将各请求关联起来(如&#xff1a;用户登录系统购物、多次购买行为…

十年探索,云上明灯,re:Invent再启掀产业风暴

15年前&#xff0c;IT基础设施有着太多的限制&#xff0c;成本高、反应慢、灵活度低&#xff0c;对于企业的创新与发展有着很大的伤害。当亚马逊推出全球第一个云计算服务简单存储 Amazon S3时&#xff0c;可能没有太多人相信&#xff0c;这些内容将会开启一个新世界的大门&…

用手机「3D探店」是种什么体验?

简介&#xff1a; 未来场景尽在眼前&#xff01;阿里云3D全景网站通过云端算法技术自动建模&#xff0c;将线下场景1:1真实还原到线上&#xff0c;让用户足不出户就可以感受到真实的3D空间漫游效果。 在手机里用3D探店打卡是种什么样的体验&#xff1f; 走进商场&#xff0c;每…

mysql bin oct_python 讲解进制转换 int、bin、oct、hex

相关免费学习推荐&#xff1a;python视频教程原理十进制转n进制都可以使用倒除法&#xff1a;对十进制进行除n的运算&#xff0c;直到商为0为止&#xff0c;然后将各个步骤中得到的余数倒着写出来.n进制转十进制&#xff1a;(例子&#xff1a;二进制转十进制)101001 > 2^5 …

java设置字体大小和颜色_Java 设置Excel图表背景填充(颜色、图片填充)

本文介绍通过Java程序来设置Excel图表背景填充的方法&#xff0c;填充时&#xff0c;可设置颜色填充或者加载图片填充&#xff1b;填充区域可设置整个图表区域或者绘图区域。设置方法参考以下内容。使用工具&#xff1a;Free Spire.XLS for Java&#xff08;免费版&#xff09;…

英特尔TCI技术落地,锐捷网络发布OCS终端云化新品

编辑 | 宋慧 出品 | CSDN 云计算 2021 年 6 月&#xff0c;国内一直深耕桌面虚拟化的厂商锐捷正式发布了新一代云桌面解决方案——锐捷三擎云桌面解决方案&#xff08; “精耕细作”桌面云市场的锐捷&#xff0c;重磅发布三擎云桌面 &#xff09;&#xff0c;其中三擎指的是终端…

从理念到实践跳跃式演进! 云的原生“免疫系统”如何有机作战?

简介&#xff1a; 7月16日&#xff0c;以“原生安全二倍速&#xff1a;全面融入基础设施”为主题的阿里云原生安全线上专题活动收官&#xff0c;诠释由云而生的能力如何解决数字经济时代的安全新挑战&#xff0c;让高等级安全作为一种基础设施&#xff0c;成为数字业务发展的“…

安卓开发替换json字符串中的数据_22个JavaScript开发技巧合集

作者&#xff1a;kancloud转发链接&#xff1a;https://www.kancloud.cn/dennis/tgjavascript/241855开发技巧1、使用var声明变量如果给一个没有声明的变量赋值&#xff0c;默认会作为一个全局变量(即使在函数内赋值)。要尽量避免不必要的全局变量。2、行尾使用分号虽然JavaScr…

Python静态类型解析工具简介和实践

简介&#xff1a; Python是一门强类型的动态类型语言&#xff0c;开发者可以给对象动态指定类型&#xff0c;但类型不匹配的操作是不被允许的。动态类型帮助开发者写代码轻松愉快&#xff0c;然而&#xff0c;俗话说&#xff1a;动态一时爽&#xff0c;重构火葬场。动态类型也带…

拥抱创新二十载,微软“创新杯”持续孵化中国青年开发者智慧创意

12月13日&#xff0c;2022 第二十届微软“创新杯”全球学生大赛&#xff08;以下简称“创新杯”&#xff09;中国区总决赛结果正式揭晓。来自西安的 Silent Talk 团队凭借Silent Talk—— Speech Rehabilitation Training 项目&#xff0c;在 22 支决赛队伍中脱颖而出&#xff…

AI和大数据结合,智能运维平台助力流利说提升核心竞争力

简介&#xff1a; 简介&#xff1a;本文整理自数智创新行——智能运维专场&#xff08;上海站&#xff09;&#xff0c;流利说最佳实践演讲&#xff1a;《基于SLS千万级在线教育平台统一监控运营实践》 作者&#xff1a; 孙文杰 流利说运维总监 元乙 阿里云智能技术专家 优质…

核桃编程:前端可观测性建设之路

简介&#xff1a; 随着核桃编程业务的快速增长&#xff0c;核心应用的系统规模和系统复杂度也在经历翻天覆地的变化。核桃技术团队不断通过新兴的技术手段维护整套系统架构的技术先进性。在3 年时间里&#xff0c;技术团队至少对整体系统架构进行了 6 次以上的重大重构&#xf…

少拿游戏来骗我,虚幻引擎5上的《黑客帝国》全新体验,画面帅到爆

整理 | 禾木木 出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09; 近日&#xff0c;由 Epic Games 发行的虚幻引擎 5 体验上线了。 以华纳兄弟公司电影《黑客帝国》为背景&#xff0c;由拉娜 沃卓斯基担任编剧和导演&#xff0c;基努 里维斯和凯瑞 - 安 莫…

python变量使用前必须先声明、并且一旦声明_初学者学习Python的30天‍-第18天-文件处理...

前文最近不是出了一个30天的Python教程&#xff0c;有很多人私信我说没有资料怎么跟着学习&#xff0c;现在他来了https://www.bilibili.com/read/cv9383238今天&#xff0c;我探讨了如何使用Python处理文件并与文件进行通信。这些天来&#xff0c;我一直在探索和分享各种Pytho…

金融数据智能峰会 | 数据规模爆炸性增长,企业如何进行精准决策?云原生数据仓库数据化运营实战分享

简介&#xff1a; 在日前的2021阿里云金融数据智能峰会——《云原生驱动数智化运营的“增长黑马”》专场上&#xff0c;阿里云数据库资深技术专家魏闯先 从数据价值链路角度切入&#xff0c;为大家解读云原生数据仓库如何支撑数据化运营、全链路营销和阿里集团双11业务&#xf…

redistemplate.opsforvalue 设置不过期_民法典即将实施!“离婚冷静期”倍受关注

还有不到一个月&#xff0c;“离婚冷静期”就要落地了。2021年1月1日起&#xff0c;《中华人民共和国民法典》(以下简称“《民法典》”)将正式施行。作为与老百姓日常生活关系最为紧密的一部法律&#xff0c;《民法典》的制定和施行备受关注&#xff0c;其中尤以“离婚冷静期”…

到底是无线最难?还是核心网最难?

作者 | 小枣君来源 | 鲜枣课堂今天这篇文章&#xff0c;我们来探讨一个通信行业的长期争议话题——到底是无线最难&#xff1f;还是核心网最难&#xff1f;众所周知&#xff0c;通信行业虽然对外统称“通信”&#xff0c;但实际上&#xff0c;内部却分为三个细分板块&#xff0…