字节码
字节码文件
文件格式
Java编译后的字节码文件格式,其文件结构定义如下:
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];
}
以下面一个最简单的一个类为例,在下面这个类中,只通过class修饰定义了一个类,其中没有定义任何常亮,变量以及方法:
class SimpleClass { }编译
魔数(magic):
4bytes, 0xCAFEBABE
版本(version):
包括主版本号和小版本号
小版本号(minor version):
2bytes,0x0000
主版本号(major version):
2bytes,0x0034
常量池:
常量池通过一个数组来保存各个常量,数组的大小-1就是常量池常量个数。针对不同类型的常量通过tag来表示。
常量池常量个数(constant pool count):
0x000D,转换为10进制就是13,
常量池(constant pool):
常量tag:
0x0A,表示一个CONSTANT_Methodref类型的常量
class_index:
0x0003,
name_and_type_index:
0x000A
常量tag:
0x07,表示一个CONSTANT_Class类型的常量
name_index:
0x000B,
常量tag:
0x07,表示一个CONSTANT_Class类型的常量
name_index:
0x000C
常量tag:
0x01, 表示一个CONSTANT_Utf8类型的常量
length:
0x0006, 表示字符串长度
bytes[length]:
0x3C696E69743E,表示字符串“<init>”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0003,表示字符串长度
bytes[length]:
0x282956,表示字符串“()V”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0004,表示字符串长度
bytes[length]:
0x436F6465,表示字符串“Code”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000F,表示字符串长度
bytes[length]:
0x4C696E654E756D6265725461626C65,表示字符串“LineNumberTable”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000A,表示字符串长度
bytes[length]:
0x536F7572636546696C65,表示字符串“SourceFile”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0010,表示字符串长度
bytes[length]:
0x53696D706C65436C6173732E6A617661,表示字符串“SimpleClass.java”
常量tag:
0x0C,表示一个CONSTANT_NameAndType类型的常量
name_index:
0x0004,
descriptor_index:
0x0005,
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000B, 表示字符串长度
bytes[length]:
0x53696D706C65436C617373,表示字符串“SimpleClass”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0010,表示字符串长度
bytes[length]:
0x6A6176612F6C616E672F4F626A656374,表示字符串“java/lang/Object”
访问控制修饰标志(access_flags):
0x0020
this_class:
0x0002
super_class:
0x0003
interfaces_count:
0x0000
interfaces[interfaces_count]:
fields_count:
0x0000
fields[fields_count]:
methods_count:
0x0001
methods[methods_count]:
方法:
access_flags:
0x0000
name_index:
0x0004
descriptor_index:
0x0005
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0006
attribute_length:
0x0000001D,表示29
info[attribute_length]:
0x00010001000000052AB70001B100000001000700000006000100000001
对info[attribute_length]的说明:Code_attribute
attribute_name_index:
就是上面对应的attribute_name_index:0x0006
attribute_length:
就是上面对应的attribute_length:0x0000001D,表示29
max_stack:
0x0001
max_locals:
0x0001
code_length:
0x00000005
code[code_length]:
0x2AB70001B1
从这里可以看出这个方法对应的代码指令就是:0x2AB70001B1,具体是些什么指令呢?
经过分析的结果就是:
0: aload_0 1: invokespecial #1 4: return
前面的数字表示对应的指令所占用的字节数,加起来正好5个字节。
aload_0对应0x2A, aload_0表示将this压入到操作栈的栈顶。
invokespecial #1对应0xB70001,其中0xB7就表示invokespecial指令。后面的0001用于计算出调用的方法在常量池中的索引:(indexbyte1 << 8) | indexbyte2, 经过计算后为1,表示java/lang/Object的<init> ()V,也就是父类Object的无参构造方法。
return对应0xB1,表示返回。
这里主要就是调用了Object的无参构造方法,然后返回。
参考:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5
exception_table_length:
0x0000
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length]:
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0007
attribute_length:
0x00000006
info[attribute_length]:
0x000100000001
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0008
attribute_length:
0x00000002
info[attribute_length]:
0x0009
到这里整个字节码class文件就全部分析完了。
另一个例子:
http://dl.iteye.com/topics/download/9ce78296-1257-311e-b4e2-faa0bd211e14
Java反编译出汇编代码可参考另一篇文章:https://lobin.iteye.com/blog/1578849
参考文章:Chapter 4. The class File Format,https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html
相关推荐
class文件结构解析字节码后文件
Java字节码分析工具,系统分析了java字节码文件,即java class类文件,对该文件中的各种成分以树的形式描述出来,只能针对未加密的class文件,一般由标准java编译器编译生成的class文件都未加密,该系统在vs2003下面...
我们都知道,Java程序最终是转换成class文件执行在虚拟机上的,那么class文件是个怎样的结构,虚拟机又是如何处理去执行class文件里面的内容呢,这篇文章带你深入理解Java字节码中的结构。 1.Demo源码 首先,编写一...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
JavaClassViewer-2.0.4, 用于理解Class文件结构。 解析出class结构,以及十六进制的表示,特别方便。 原下载地址: http://www.softpedia.com/get/Programming/File-Editors/Java-Class-Viewer.shtml。另外也可以参考...
* 2:获得文件句柄当做是输入一个字节码流,需要对这个输入流进行读取 * 3:读取到输入流后,需要读取生成字节流 * 4:一行一行的输出。readline()。 * 备注:需要考虑的是异常情况 * @param filePath */...
一个解析java class文件的代码
详细介绍ASM框架的API、Class文件结构解析、HotSpot虚拟机类加载源码分析、动态代理与字节码插桩的实现。
a library written by c language,for parsing the standard java class byte codes
JavaBytecodeAnalyzer 解析 Java 字节码,学习字节码指令集 解析 class 文件为字节码,以熟悉 class 文件结构 学习 java bytecode 指令集
ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
Java反编译工具,解析class字节码文件。 解析class字节码文件
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
如果您只想运行已编译的字节码,则只需一个Python解释器。 运行测试 该项目带有许多单元测试。 如果运行shell脚本test.sh ,它将在示例目录中编译Java文件并运行单元测试。 您将能够看到通过了多少测试以及失败了...
ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class文件...
使用Java编程语言,对.class文件进行解析,类似于javap -v filename指令的效果,但是没有对attibutes属性进行解析,需要学习的可以下载,程序运行的效果在本人的博客的附录中
4. Java字节码程序是可以在Java虚拟机上执行的。( ) 答案:√ [考点范围] JAVA简介 5. Java程序对计算机硬件平台的依赖性很低。( ) 答案:√ [考点范围] JAVA简介 6. Java可以用来进行多媒体及网络编程。( ) ...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...