java class 文件格式解析
前言
大约5年前,想研究javaassistant,cglib等字节码操作的相关类库,来对class进行增强,当要到要操作字节码的时候,发现无法继续下去了,只能放弃。
学习jvm字码,需要理解class的组成方式,对汇编,操作栈比较了解,无奈,只好重新学习编译原理,汇编等知识,再来看jvm规范,现在理解起来,容易很多了。
Class文件规范
编译后被 Java 虚拟机所执行的代码使用了一种平台中立(不依赖于特定硬件及操作系统的)
的二进制格式来表示,并且经常(但并非绝对)以文件的形式存储,因此这种格式被称为 Class
文件格式。Class 文件格式中精确地定义了类与接口的表示形式,包括在平台相关的目标文件格
式中一些细节上的惯例
相关文档
https://docs.oracle.com/javase/specs/jvms/se15/html/jvms-4.html
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
下面,我们开始解析每个字段是如何标识出来的
其中 u4, u2 代表什么意思
u 表示无符号数 后面的数字 表示 占用多少字节
u4 占用4个字节
u2 占用2个字节
- magic 占用4个字节,(ca fe ba be )

minor_version 子版本号 ,2个字节数字

major_version 主版本好 2个字节的数字

- constant_pool_count 常量池数目 2个字节的数字

- constant_pool[constant_pool_count-1] 常量池数组

- access_flags 访问标识 2个字节数字
- this_class class名称的索引,
- super_class 超类的名称索引
- interfaces_count 接口的数目
- interfaces[interfaces_count] 接口的数组
- fields_count 字段数目
- fields[fields_count] 字段的数组
- methods_count 方法的数目
- methods[methods_count] 方法的数组
- attributes_count 属性的数目
- attributes[attributes_count] 属性的数组
如何自己动手解一个class文件
相信大部分第一样看到上面的协议时候,能看弄,但是要自己动手解析出每个字段的含义出来,
就无法下手了,
- 读取class文件
FileInputStream in= new FileInputStream("d:/my.class");
- 读取 magic ,(magic u4 占用4个字节)
byte[] bytes=new byte[4];
in.read(bytes);
- 读取 minor_version u2 占用2个字节
byte[] minorByte=new byte[2];
in.read(minorByte);
- 读取 major_version u2 占用2个字节
byte[] majorVersion=new byte[2];
in.read(majorVersion);
看到上面的解析,是否明白了,其实还是很有规律的,只要你认真看协议文档(要看好多遍才行)
最终解析class 文档就是这样的
ClassFile classFile = new ClassFile();
PcBufferInputStream in = new PcBufferInputStream(new FileInputStream(fileName));
classFile.setMagic(readMagic(in));
classFile.setMinorVersion(readMinorVersion(in));
classFile.setMajorVersion(readMajorVersion(in));
classFile.setConstantPoolCount(readConstantPoolCount(in));
classFile.setCpInfo(readCpInfo(in));
classFile.setAccessFlags(readAccessFlags(in));
classFile.setThisClass(readThisClass(in));
classFile.setSuperClass(readSuperClass(in));
classFile.setInterfacesCount(readInterfacesCount(in));
// u2 interfaces interfaces_count
classFile.setInterfaces(readInterfaces(in));
// u2 fields_count
classFile.setFieldsCount(readFieldsCount(in));
// field_info fields fields_count
classFile.setFields(readFields(in));
// u2 methods_count 1
// method_info methods methods_count
classFile.setMethodsCount(readMethodsCount(in));
classFile.setMethods(readMethods(in));
// u2 attribute_count 1
classFile.setAttributeCount(readAttributeCount(in));
// attribute_info attributes attributes_count
classFile.setAttributes(readAttributes(in));
classFile.setPcRecord(recordMap);
return classFile;
java class 解析源码开源地址
https://gitee.com/venus-suite/java-classViewer
如果喜欢,欢迎stars 哦
java class 文件格式解析的更多相关文章
- (4) 深入理解Java Class文件格式(三)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21557357 首先, 让我们回顾一下关于class文件格式的之前两篇博客的主要内容. 在 ...
- Java 面试知识点解析(三)——JVM篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- (10) 深入了解Java Class文件格式(九)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22432599 经过前八篇关于class文件的博客, 关于class文件格式的内容也基本上讲 ...
- (9) 深入了解Java Class文件格式(八)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22205831 在本专栏的第一篇文章 深入理解Java虚拟机到底是什么 中, 我们主要讲解了 ...
- (8) 深入理解Java Class文件格式(七)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22091529 本专栏列前面的一系列博客, 对Class文件中的一部分数据项进行了介绍. 本 ...
- (7) 深入了解Java Class文件格式(六)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21888943 经过前几篇文章, 终于将常量池介绍完了, 之所以花这么大的功夫介绍常量池, ...
- (6) 深入理解Java Class文件格式(五)
前情回顾 本专栏的前几篇博文, 对class文件中的常量池进行了详细的解释. 前文讲解了常量池中的7种数据项, 它们分别是: CONSTANT_Utf8_info CONSTANT_NameAndTy ...
- (5) 深入理解Java Class文件格式(四)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21658415 前情回顾 在上一篇博客深入理解Java Class文件格式(三) 中, ...
- (3) 深入理解Java Class文件格式(二)
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/21487287 在上一篇文章 深入理解Java Class文件格式(一) 中, 介绍了c ...
随机推荐
- 前端知识之BOM和DOM
前端基础之BOM和DOM windw对象 指浏览器窗口,所有的浏览器都支持window对象 常用的window方法 window.innerHeight 浏览器窗口的内部高度 window.inner ...
- 6月20日 Django中ORM介绍和字段、字段参数、相关操作
一.Django中ORM介绍和字段及字段参数 二.Django ORM 常用字段和参数 三.Django ORM执行原生SQL.在Python脚本中调用Django环境.Django终端打印SQL语句 ...
- FrameScan CMS漏洞扫描
工具简介 GithubL:https://github.com/qianxiao996/FrameScan FrameScan是一款python3编写的简易的cms漏洞检测框架,支持多种检测方式,支持 ...
- 利用DNSLog实现无回显注入
测试一些网站的时候,一些注入都是无回显的,我们可以写脚本来进行盲注,但有些网站会ban掉我们的ip,这样我们可以通过设置ip代理池解决, 但是盲注往往效率很低,所以产生了DNSlog注入 DNSLOG ...
- JavaScript 里的 'this' 的一般解释
本文旨在帮助自己和大家理解 JS 里的 this, 翻译.整理并改写自本人关注的一个博主 Dmitri Pavlutin,原文链接如下: https://dmitripavlutin.com/gent ...
- 『现学现忘』Docker基础 — 34、DockerFile文件详解
目录 1.DockerFile文件说明 2.Dockerfile构建过程解析 (1)Docker容器构建三步骤 (2)Dockerfile文件的基本结构 (3)Dockerfile注意事项 (4)Do ...
- Jpa 自定义@Query查询总结
第一种方式 能够请求,,返回数据为 不带字段 第二种方式 报错 第三种方式 正确 总结:如果返回 List<TbRegionDO> 不能 有as存在 ,,只能查询所有 select s ...
- Linux 下命令有哪几种可使用的通配符?分别代表什么含义?
"?"可替代单个字符. "*"可替代任意多个字符. 方括号"[charset]"可替代 charset 集中的任何单个字符,如[a-z],[ ...
- 为什么要用 Dubbo?
随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越 复杂,诞生了面向服务的架构体系(SOA), 也因此衍生出了一系列相应的技术,如对服务提供.服务调用.连接处理.通信 协议.序列化 ...
- ros中关于节点、话题、服务以及自定义消息等在终端中的常用命令
以下面的计算力图说明 节点相关常用命令 在终端中查看项目中有哪些节点命令:rosnode list 有了节点信息想要查看节点中到底发布订阅了哪些话题,作为服务端服务类型或者作为客户端需要的服务类型以上 ...