字节码
字节码文件
文件格式
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
相关推荐
Java字节码文件查看工具,如JD-GUI,是开发者们深入理解Java应用程序内部机制的重要辅助工具。这类工具能够帮助我们查看并分析.class文件,这些文件是Java源代码经过编译后的二进制形式,包含了运行时所需的所有指令...
标题中的“class运行器v6”是一个用于执行Java字节码文件的应用程序,它允许用户在没有完整Java环境的情况下运行单个.class文件。这个工具可能是由开发者为了方便测试或教学目的而创建的,特别是对于那些不熟悉或者...
【Java字节码结构解析】 Java程序在执行时,首先需要通过Java编译器将源代码(.java文件)编译成二进制的字节码文件(.class文件),这些字节码由Java虚拟机(JVM)解析并执行。深入理解字节码结构有助于我们了解...
class文件结构解析字节码后文件
Java字节码分析工具,系统分析了java字节码文件,即java class类文件,对该文件中的各种成分以树的形式描述出来,只能针对未加密的class文件,一般由标准java编译器编译生成的class文件都未加密,该系统在vs2003下面...
`.docx`文档可能详细解析了Java字节码中的各个指令,包括它们的编码、含义、操作数和实际应用。通过阅读这份文档,你可以深入理解JVM如何执行字节码,以及如何通过反编译工具如jad、 jclasslib来分析`.class`文件。 ...
Java字节码编辑器是一种工具,它允许开发者直接编辑Java程序编译后的`.class`文件,而不是反编译后再重新编译。这种编辑器对于理解、调试和优化Java代码非常有用,尤其是对于那些无法访问源代码或者需要进行底层操作...
在实际开发中,解析Class文件的工具和库有很多,如javap(Java字节码反汇编器)、ASM、BCEL、Javassist等。这些工具可以帮助开发者深入理解字节码,甚至自动生成或修改字节码,实现一些高级功能。 总而言之,Java...
Java字节码文件反编译是一项重要的技术,它允许开发者查看和理解已编译的Java类文件(.class文件)内部的源代码结构。在Java中,源代码被编译成字节码,这是一种中间语言,由Java虚拟机(JVM)执行。然而,有时我们...
`jclasslib`则是一款图形化的Java字节码浏览器,主要用于解析和展示Java字节码文件(`.class`文件)的内容。它可以直观地显示字节码指令和常量池中的信息,并且提供了一定程度上的编辑功能,使得用户可以直接在图形...
C++库解析Java字节码的主要目的是为了能够读取、分析或者修改Class文件的结构。这在逆向工程、性能优化、安全分析以及跨语言集成等场景中非常有用。例如,开发者可能需要知道类的结构、方法签名、常量池信息,或者对...
1. **Luyten 0.5.4**: 这是一个跨平台的Java字节码查看器和编辑器,可以帮助开发者查看并修改`.class`文件。Luyten提供了图形化的界面,使得字节码的分析和修改变得更加直观。你可以通过加载`.class`文件,查看其...
1. **Java字节码**:Java源代码编译后生成的是.class文件,其中存储的就是字节码,这是一种中间表示,与具体的硬件平台无关。每条字节码指令占用一个字节,由操作码和操作数组成,用于JVM执行。 2. **类文件结构**...
1. **Java字节码结构**: - 类文件以魔数`CAFEBABE`开头,用于识别文件格式。 - 接着是版本信息,包括字节码版本号和常量池计数器。 - 常量池是类文件的核心部分,包含字符串、类名、方法名、字段名等各种常量。 ...
Python是一种强大的、动态...它需要对Java字节码格式有深入的理解,同时也需要熟悉Python的字节操作和数据结构。通过实践这样的项目,开发者可以增强跨语言编程的能力,同时也能对Java和Python的底层机制有更深的认识。
Java字节码反编译工具是开发者们在研究或调试Java程序时常用的一种辅助软件,它能够将已编译的Java字节码(.class文件)转换回可读性较高的源代码形式。这样的工具使得开发者可以查看和理解第三方库或者无法获取源代码...
**JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...
5. ** Krakatau**:这是一款相对新颖的反编译工具,专注于Java字节码的解析和重构。Krakatau对于研究字节码和理解底层工作原理非常有用。 反编译的过程通常包含以下几个步骤: 1. **字节码解析**:反编译器首先...