Class文件分析
java源码和class文件
源码:
package classloader; public class TestCase {
private int value;
public int test(){
return value++;
}
}
使用editplus 经过hex viewer解压方式打开的Class文件:
Class文件组成:
1、00000000~00000003 (u4 0xCA FE BA BE)魔数 Magic Number
2、00000004~00000005(u2 0x 00 00 )次版本号Minor Version
3、00000006~00000007(u2 0x00 34 )主版本号Major Version,由主版本号和次版本号可知这个Class文件是jdk1.8进行编译的
4、00000008~00000009(u2 0x00 13)常量池容量计数值constant_pool_count,并且这个容量计数是从1开始的。
0x0013对应的十进制是19,因为是从1开始计数的,所以常量池里面的数量应该还19-1=18个,使用javap -v命令查看常量池的数量正好就是18个
图1、TestCase.class文件字节码信息
5、0000000a(u1 0A)
通过查询我另外一篇文章中的《表3、常量池中表结构类型》中可知,0x0A对应的是类中的方法的符号引用(CONSTANT_methodref_info)
6、0000000b~0000000c(u2 0x00 04)
指向声明方法的类描述符CONSTANT_Class_info的索引项,由图1我们可以看到常量池中索引为1的是#1=Methdref 对应的类索引位置是#4,换成16进制正好是0x0004
7、0000000d~0000000e(u2 0x00 0F)
指向名称以及类型描述符CONSTANT_Name_type的索引项,由图1我们可以看到常量池中索引为1的是#1=Methdref 对应的类索引未知是#15,换成16进制正好是0x000F
8、0000000f(u1 0x09):通过查询《表3、常量池中表结构类型》可知,0x09对应的是类中字段的符号引用
9、00000010~00000011(u2 0x00 03)
指向声明方法的类描述符CONSTANT_Class_info的索引项,由图1我们可以看到常量池中索引为2的是#2=Fieldref 对应的类索引位置是#3,换成16进制正好是0x0002
10、00000012~00000013(u2 0x00 10)
指向名称以及类型描述符CONSTANT_Name_Type的索引项,由图1我们可以看到常量池中索引为2的是#2=Fieldref对应的类索引未知是#16,换成16进制正好是0x0010
11、00000014~00000016(u1+u2 0x07 00 11)
通过查询《表3、常量池中表结构类型》可知07对应的是类或接口的符号引用 0011指向的是全限定名的索引(0x0011=17)
12、00000017~00000019(u1+u2 0x07 00 12)
通过查询《表3、常量池中表结构类型》可知07对应的是类或接口的符号引用 0012指向的是全限定名的索引(0x0012=18)
13、0000001a~00000021(u1+u2+u2*u1 0x01 00 05 76 61 6C 75 65)
标志位01对应的Utf-8类型的常量,通过《表4、常量表中的各种表结构可知》,utf-8类型常量结构是(tag+length+bytes),所以length(00 05)=5,所以76 61 6C 75 65正好对应的是value字段,也就是说这个常量代表的是变量value
14、00000022~00000077
这分别代表了常量池中#5~#14的常量,此处不再一一叙述
15、00000078~0000007c(u1+u2+u2 0x0C 0007 0008)
通过表3可知0c对应的Constant_NameAndType_info,0007 是指向该字段或方法名称常量项的索引,0008指向的是该字段或方法的描述符常量项的索引,#7对应的是<init>变量名,相关的内容将会在一篇中进行描述,此处就先不进行解释
16、0000007d~00000081(u1+u2+u2 0x0C 0005 0006)
通过《表3、常量池中表结构类型》可知0c对应的Constant_NameAndType_info,0005 是指向该字段或方法名称常量项的索引,0006指向的是该字段或方法的描述符常量项的索引,因为#5和#6分别对应的是value的字段名和类型,所以0000007d~00000081描述的是value字段的名称和类型
17、00000082~00000098(tag+length+bytes 0x 01 0014 ...)
由tag=01可知这也是一个utf-8类型的常量,长度0014=20 ,通过后面长度为20 的字节可知这部分描述的是类名的全称(classLoader/TestCase),不过将.换成了/
18、00000098~000000ab(tag+length+bytes 0x 01 0010 ...)
由tag=01可知这也是一个utf-8类型的常量,长度0010=16 ,通过后面长度为16 的字节可知这部分描述的是类名的全称(java/lang/Obeject),不过将.换成了/
19、000000ac~000000ad(u2 00 21)
紧跟着常量池之后的这两个字节描述的是类或接口的访问标志,0x0021=0x0020|0x0001,通过查询《表5、类文件访问属性》可知,这个类的访问标志是ACC_PUBLIC和ACC_SUPER
20、000000ae~000000b3(u2+u2+u2 0003 0004 0000)
这个三个u2类型的分别代表的是常量池中类索引位置为0003(#3),父类索引位置是0004(#4),接口索引集合的大小为0000(0)
21、000000b4~000000bd(u2+u2+u2+u2 0001 0002 0005 0006 0000)
- 这四个u2类型的数据项分别代表的是类中变量的个数为0001(1)个
- 变量的访问标志是0002(通过查询《表7、字段表访问修饰符》可以,这个变量的访问标志是ACC_PRIVATE)
- 变量名在常量池中对应的索引是0005(#5)
- 变量类型在常量池中对应的索引位置0006(#6),属性的个数为0000(0)个,如果在本例中的变量value前面加个final修饰的话,属性的个数就会变成0001,并且后面会跟随属性的相关信息
22、000000be~000000c7(u2+u2+u2+u2+u2 0002 0001 0007 0008 0001)
- 方法的个数0002(2个 一个是test方法,一个是Object的<init>方法,其中22~24步骤代表的事Object中的<init>方法,25~27代表的是我们编写的test()方法)
- 方法的访问标志0001(通过《表10、方法表标志位列表》可知对应的访问标志是ACC_PUBLIC)
- 方法名在常量池中对应的索引位置0007(#7)
- 方法的描述符在常量池中对应的索引位置0008(#8)
- 方法的属性的数量0001(1)个
23、000000c9~000000de(u2+u4+u2+u2+u4+u1*u4+u2+u2 0009+0000001D+0001+0001+00000005+2AB70001B1+0000+0001)
- 方法的属性对应的常量池索引位置0009(#9),对应常量是Code,说明此属性是方法的字节码描述
- 属性的长度为0x1D(29)
- 方法操作数栈深度的最大值为0001(1)
- 局部变量表需要分配的存储空间(单位Slot),对于byte、char、float、int、short、boolean和returnAddress等长度不超过32位的数据类型,每个局部变量占用1个Slot,而double和long这两种64位的数据类型则需要两个Slot来存放
- java源程序编译后的的成的字节码长度00000005(5)
- java源程序编译后的的成的字节码长度java源程序编译后的的成的字节码(字节码指令表可参考《
JVM 虚拟机字节码指令表
》),翻译2AB70001B1的过程为
2A:对应的指令是aload_0,将第0个Slot中为引用类型的本地变量推送到操作数栈顶
B7:对应的指令是invokespecial(调用超类构建方法, 实例初始化方法, 私有方法),这个方法有一个u2类型的参数说明具体调用哪个方法,它指向常量池中一个CONSTANT_Methodref_info常量,即
此方法的方法符号引用
0001:这是invokespecial的参数,查询常量池可知是Object的<init>方法
B1:查询虚拟机字节码指令表可知B1对应的指令为return
- 异常表的长度0000(0)个,因为本实例代码中没有使用try...catch,所以没有显式的异常
- 属性的个数0001(1)个
24、000000df~000000ea (u2+ u4+u2+u2+u2+ 000A+00000006+0001+0000+0003)
- 属性名称对应的索引 000A指向的是常量池中的#10(LineNumberTable)
- 属性的长度00006(6)个
- line_number_table的长度为0001
- 字节码对应的行号是0000行
- java源码对应的行数是0003(3)行
25、000000ea~000000f2(u2+u2+u2+u2 0001 000B 000C 0008 0001)
- 方法的访问标志0001(通过《表10、方法表标志位列表》可知对应的访问标志是ACC_PUBLIC)
- 方法名在常量池中对应的索引位置000B(#11,对应的是test)
- 方法的描述符在常量池中对应的索引位置000C(#12)
- 方法的属性的数量0001(1)个
26、000000f3~0000010b(u2+u4+u2+u2+u4+u1*u4+u2+u2 0009+0000001F+0002+0001+00000007+2AB400020460AC+0000+0001)
- 方法的属性对应的常量池索引位置0009(#9),对应常量是Code,说明此属性是方法的字节码描述
- 属性的长度为0x1F(30)
- 方法操作数栈深度的最大值为0002(1)
- 局部变量表需要分配的存储空间(单位Slot),对于byte、char、float、int、short、boolean和returnAddress等长度不超过32位的数据类型,每个局部变量占用1个Slot,而double和long这两种64位的数据类型则需要两个Slot来存放
- java源程序编译后的的成的字节码长度为00000007(7)
- java源程序编译后的的成的字节码长度java源程序编译后的的成的字节码(字节码指令表可参考《
JVM 虚拟机字节码指令表
》),翻译2AB70001B1的过程为
2A:对应的指令是aload_0,将第0个Slot中为引用类型的本地变量推送到操作数栈顶(这里的引用类型的本地变量指的就是变量value)
B4:对应的指令是getfield(获取指定类的实例域, 并将其压入栈顶),由javap命令查询的内容可知,这里的2A代表的是将value字段的实例压入栈顶
0002:这是getfield的参数,指明Field字段对应的类在常量池中的索引为#2
04:查询虚拟机字节码指令表可知04对应的指令为 将int型1推送至栈顶(这里int型1就是return中的+1)
60:查询虚拟机字节码指令表可知60对应的指令为 将栈顶两int型数值相加并将结果压入栈顶(栈顶的两个int类型的数分别是变量value和数字1)
AC:查询虚拟机字节码指令表可知04对应的指令为 从当前方法返回int(也就是返回最终的value+1的结果)
- 异常表的长度0000(0)个,因为本实例代码中没有使用try...catch,所以没有显式的异常
- 属性的个数0001(1)个
27、0000010c~00000117(u2+ u4+u2+u2+u2+ 000A+00000006+0001+0000+0006)
- 属性名称对应的索引 000A指向的是常量池中的#10(LineNumberTable)
- 属性的长度00006(6)个
- line_number_table的长度为0001
- 字节码对应的行号是0000行
- java源码对应的行数是0006(6)行
28、0000011b~00000122(u2+u4+u2 0001+00000006+0001)这是个sourceFile文件,对应的是Object类
- sourceFile属性名称对应索引位置为#1
- 该属性的长度为6
- sourceFile属性对应索引位置为#1
29、00000123~0000012a(u2+u4+u2 000D+00000002+000E)这是个sourceFile文件,对应的是我们编写的类TestCase.java
- sourceFile属性名称对应索引位置为#13
- 该属性的长度为2
- sourceFile属性对应索引位置为#14(TestCase.java)
Class文件分析的更多相关文章
- linux实践之ELF文件分析
linux实践之ELF文件分析 下面开始elf文件的分析. 我们首先编写一个简单的C代码. 编译链接生成可执行文件. 首先,查看scn15elf.o文件的详细信息. 以16进制形式查看scn15elf ...
- 蓝屏 Dump文件分析方法
WinDbg使用有点麻烦,还要符号表什么的.试了下,感觉显示很乱,分析的也不够全面... 试试其他的吧!今天电脑蓝屏了,就使用其dump文件测试,如下: 1.首先,最详细的,要属Osr Online这 ...
- KEIL MDK输出map文件分析
一.文件分析流程 1.第一部分:Section Cross References 主要是各个源文件生成的模块之间相互引用的关系. stm32f10x.o(STACK) refers (Special) ...
- ecshop init.php文件分析
1. ecshop init.php文件分析 2. <?php 3. 4. /** 5. * ECSHOP 前台公用文件 6. * ===================== ...
- [转载]mysql慢日志文件分析处理
原文地址:mysql慢日志文件分析处理作者:maxyicha mysql有一个功能就是可以log下来运行的比较慢的sql语句,默认是没有这个log的,为了开启这个功能,要修改my.cnf或者在mysq ...
- 使用 Eclipse Memory Analyzer 进行堆转储文件分析
Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个组成项目中之一,它是一个功能丰富的 JAVA 堆转储文件分析工具,可 ...
- Android JNI入门第三篇——jni头文件分析
一. 首先写了java文件: public class HeaderFile { private native void doVoid(); native int doShort(); native ...
- Java class文件分析工具 -- Classpy
Classpy Classpy是一个图形化的class文件分析工具,功能和javap类似,界面主要參考了Java Class Viewer: 为什么要又一次创造轮子? 写这个工具花了将近一周的时间.那 ...
- STM32固件库文件分析
STM32固件库文件分析 1.汇编编写的启动文件 startup/stm32f10x.hd.s:设置堆栈指针,设置pc指针,初始化中断向量,配置系统时钟,对用c库函数_main最后去c语言世界里. 2 ...
- Nmap脚本文件分析(AMQP协议为例)
Nmap脚本文件分析(AMQP协议为例) 一.介绍 上两篇文章 Nmap脚本引擎原理 编写自己的Nmap(NSE)脚本,分析了Nmap脚本引擎的执行过程,以及脚本文件的编写,这篇文章将以解析AMQ ...
随机推荐
- Grapher - Change how graphs look
[Change how graphs look] Pan and zoom the graph 工具条如下: Change the type of graph 开场的Graph Template在Me ...
- blocking network call
[blocking network call] 阻塞的网络调用: 1.gethostbyname(): does not return until it has succeeded or failed ...
- S 导客户主数据 及更新销售团队、组织、品牌
一.导入客户主表(INSERT) EXCEL模板 [Public] ConnectString=host="siebel://10.10.0.46:2321/HC_CRM/SMObjMgr_ ...
- php防止会话固定攻击
问题:希望确保应用不会受到会话固定攻击,即攻击者强制用户使用一个预定义的会话id. 解决方案:要求使用会话cookie但会话标识符不追加到URL,另外要频繁地生成新会话ID: <?php ini ...
- mybatis框架入门程序:演示通过mybatis实现数据库的插入操作中实现返回结果的获取
1.mybatis实现数据库的插入操作可以查看https://www.cnblogs.com/wyhluckdog/p/10149895.html这篇博文,这里面的插入操作没有返回结果,所以这篇博文就 ...
- 邮槽 匿名管道 命名管道 剪贴板 进程通讯 转自http://www.cnblogs.com/kzloser/archive/2012/11/04/2753367.html#
邮槽 通信流程: 服务器 客户端 注意: 邮槽是基于广播通信体系设计出来的,它采用无连接的不可靠的数据传输 邮槽可以实现一对多的单向通信,我们可以利用这个特点编写一个网络会议通知系统,而且实现这一的系 ...
- hive分隔符总结
ascii对应的表Char Dec Oct Hex | Char Dec Oct Hex | Char Dec Oct Hex | Char Dec Oct Hex ----------------- ...
- ios10适配
1: 去除打印多余的log信息: xcode-->Product-->Scheme-->edite Scheme 中在Ecvironment Variables 中添加OS_ACTI ...
- 团体程序设计天梯赛L2-023 图着色问题 2017-04-17 09:28 269人阅读 评论(0) 收藏
L2-023. 图着色问题 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 图着色问题是一个著名的NP完全问题.给定无向图 G ...
- Python学习-14.Python的输入输出(三)
在Python中写文件也是得先打开文件的. file=open(r'E:\temp\test.txt','a') file.write('append to file') file.close() 第 ...