热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【jvm】04我偷偷改了你编译后的class文件

【jvm】04-我偷偷改了你编译后的class文件欢迎关注b站账号公众号【六边形战士夏宁】,一个要把各项指标拉满的男人。该文章已在github目录收录。屏幕前的大帅比
【jvm】04-我偷偷改了你编译后的class文件

欢迎关注b站账号/公众号【六边形战士夏宁】,一个要把各项指标拉满的男人。该文章已在github目录收录。
屏幕前的大帅比大漂亮如果有帮助到你的话请顺手点个赞、加个收藏这对我真的很重要。别下次一定了,都不关注上哪下次一定。


  • gitee目录
  • csdn目录
  • 可直接运行的完整代码
  • 视频讲解
  • 上一篇
  • 下一篇

1.准备工作

准备一份代码

public class TestEntity {private String name;
}

编译所得

cafe babe 0000 0034 0012 0a00 0300 0f07
0010 0700 1101 0004 6e61 6d65 0100 124c
6a61 7661 2f6c 616e 672f 5374 7269 6e67
3b01 0006 3c69 6e69 743e 0100 0328 2956
0100 0443 6f64 6501 000f 4c69 6e65 4e75
6d62 6572 5461 626c 6501 0012 4c6f 6361
6c56 6172 6961 626c 6554 6162 6c65 0100
0474 6869 7301 002e 4c63 6f6d 2f65 7861
6d70 6c65 2f64 656d 6f2f 6c65 7373 6f6e
2f6a 766d 2f63 6c61 7a7a 2f54 6573 7445
6e74 6974 793b 0100 0a53 6f75 7263 6546
696c 6501 000f 5465 7374 456e 7469 7479
2e6a 6176 610c 0006 0007 0100 2c63 6f6d
2f65 7861 6d70 6c65 2f64 656d 6f2f 6c65
7373 6f6e 2f6a 766d 2f63 6c61 7a7a 2f54
6573 7445 6e74 6974 7901 0010 6a61 7661
2f6c 616e 672f 4f62 6a65 6374 0021 0002
0003 0000 0001 0002 0004 0005 0000 0001
0001 0006 0007 0001 0008 0000 002f 0001
0001 0000 0005 2ab7 0001 b100 0000 0200
0900 0000 0600 0100 0000 0300 0a00 0000
0c00 0100 0000 0500 0b00 0c00 0000 0100
0d00 0000 0200 0e

可使用javap -verbose TestEntity.class辅助查看

安装jclasslib

2.class文件结构


类型名称数量
u4magic1
u2minor_version1
u2major_version1
u2constant_pool_count1
cp_infoconstant_poolconstant_pool_count - 1
u2access_flags1
u2this_class1
u2super_class1
u2interfaces_count1
u2interfacesinterfaces_count
u2fields_count1
field_infofieldsfields_count
u2methods_count1
method_infomethodsmethods_count
u2attributes_count1
attribute_infoattributesattributes_count

具体的

3.实例解析

1)cafe babe
这个就是开头魔数占4个字节
2)0000
代表次版本号占2个字节,16进制转10进制为0,表示此版本号为0
3)0034
代表主版本号占2个字节,16进制转10进制为52,表示此版本号为1.8。51代表的是1.7以此类推,可以在idea打开class文件有提示。

javap的部分编译片段

Constant pool:#1 = Methodref #3.#15 // java/lang/Object."":()V#2 = Class #16 // com/example/demo/lesson/jvm/clazz/TestEntity#3 = Class #17 // java/lang/Object#4 = Utf8 name#5 = Utf8 Ljava/lang/String;#6 = Utf8 #7 = Utf8 ()V#8 = Utf8 Code#9 = Utf8 LineNumberTable#10 = Utf8 LocalVariableTable#11 = Utf8 this#12 = Utf8 Lcom/example/demo/lesson/jvm/clazz/TestEntity;#13 = Utf8 SourceFile#14 = Utf8 TestEntity.java#15 = NameAndType #6:#7 // "":()V#16 = Utf8 com/example/demo/lesson/jvm/clazz/TestEntity#17 = Utf8 java/lang/Object

4)0012
16进制转10进制为18,代表常量池内数量为17个。至于哪17个javap命令写的还是很清楚的。但实际上是18个,因为默认有个null占了0号位。
5)0a
16进制转10进制为10,在常量池中代表方法引用,可查看附录
5)00 03
16进制转10进制为3,在常量池中表示索引,即第3个常量,查看可知指向了Object
6)00 0f
16进制转10进制为15,在常量池中表示索引,即第15个常量,连起来的意思就是常量池里面有个object的初始化方法
7)07
16进制转10进制为70,在常量池中代表class,可查看附录

字节码文件以此类推

4.字节码命令

0 aload_0
1 invokespecial #1 >
4 return

如上命令分别表示1.将this入栈,2.执行object的init方法3.出栈

5.知识补充

1)java agent可以在main函数之前执行,可以用于传统aop,也是依赖字节码

2)静态代理是直接修改字节码完成的

3)编译检查也是可以通过class文件完成的

6.附录


6.1访问权限查询手册


flag_namevaluedesc
ACC_PUBLIC0x0001public修饰符号
ACC_PRIVATE0x0002表示私有的
ACC_PRIVATE0x0004protected
ACC_PRIVATE0x0008static
ACC_FINALOx0010final
ACC_SUPEROx0020通过invokeSpecial指令可以调用父类的方法
ACC_INTERFACE0x0200标识是一个接口
ACC_ABSTRACT0x0400表示是一个抽象类
ACC_SYNTHETIC0x1000该class是动态生成的没有源文件
ACC_ANNOTATION0x2000是一个注解类型类的访问权限查询手册
ACC_ENUM0x4000表示是一个枚举类型
ACC_PRIVATE0x8000表示这是一个模块

6.2Field_info 字段表结构


类型名称数量
u2access_flag(权限修饰符)1
u2name_index(字段名称索引)1
u2descciptor_index(字段描述索引)1
u2attribute_count(属性表个数)1
attribute_infoattributesattribute_count

6.3Method_info 字段表结构


类型名称数量
u2access_flag(权限修饰符)1
u2name_index(方法名称索引)1
u2descciptor_index(方法描述索引)1
u2attribute_count(属性表个数)1
attribute_infoattributesattribute_count

6.4attribute_info 结构


类型名称数量
u2attribute_name_index1
u4attribute_length1
u1info[attribute_length]1

6.5常量池flag标注


常量项目类型描述
CONSTANT_Utf8_infotagu1值为1
-lengthu2UTF-8编码的字符串占用了的字节数
-bytesu1长度为length的UTF-8编码的字符串
CONSTANT_Integer_infotagu1值为3
-bytesu4按照高位在前存储的int值
CONSTANT_Float_infotagu1值为4
-bytesu4按照高位在前存储的float值
CONSTANT_Long_infotagu1值为5
-bytesu8按照高位在前存储的long值
CONSTANT_Double_infotagu1值为6
-bytesu8按照高位在前存储的double值
CONSTANT_Class_infotagu1值为7
-indexu2指向全限定名常量项的索引
CONSTANT_String_infotagu1值为8
-inedxu2指向字符串字面量的索引
CONSTANT_Fieldref_infotagu1值为9
-indexu2指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项
-indexu2指向字段描述符CONSTANT_NameAndType_info的索引项
CONSTANT_Methodref_infotagu1值为10
-indexu2指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项
-indexu2指向字段描述符CONSTANT_NameAndType_info的索引项
CONSTANT_InterfaceMethodref_infotagu1值为11
-indexu2指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项
-indexu2指向字段描述符CONSTANT_NameAndType_info的索引项
CONSTANT_NameAndType_infotagu1值为12
-indexu2指向该字段或方法名称常量项的索引
-indexu2指向该字段或描述名称常量项的索引
CONSTANT_MethodHandle_infotagu1值为15
-reference_kindu1值必须在1~9之间它决定了方法句柄的类型。方法类型的句柄类型的值表示方法句柄的字节码行为
-reference_indexu2值必须是对常量池的有效索引
CONSTANT_MethodHandle_infotagu1值为16
-descriptor_indexu2值必须是对常量池的有效索引。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示方法的描述符
CONSTANT_MethodHandle_infotagu1值为17
-bootstrap_method_attr_indexu2值必须是对当前class文件中引导方法表的bootstrap_methods[]数组的有效索引
-name_and_type_indexu2值必须是对常量池的有效索引。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示方法的描述符
CONSTANT_InvokeDynamic_infotagu1值为18
-bootstrap_method_attr_indexu2值必须是对当前class文件中引导方法表的bootstrap_methods[]数组的有效索引
-name_and_type_indexu2值必须是对常量池的有效索引。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示方法的描述符
CONSTANT_Module_infotagu1值为19
-name_indexu2值必须是对常量池的有效索引。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示模块名字
CONSTANT_Module_infotagu1值为20
-name_indexu2值必须是对常量池的有效索引。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示模包名称

参考资料

《深入理解Java虚拟机》-周志明


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 解决.net项目中未注册“microsoft.ACE.oledb.12.0”提供程序的方法
    在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错“未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”。本文提供了解决这个问题的方法,包括错误描述和代码示例。通过注册提供程序和修改连接字符串,可以成功读取excel文件信息。 ... [详细]
author-avatar
软装之家888
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有