`
lobin
  • 浏览: 425690 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java字节码(class)文件结构解析

 
阅读更多

 

字节码

 

字节码文件

 

文件格式

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 {

}
编译
反汇编如下:
>javap -c SimpleC
lass
Compiled from "SimpleClass.java"
class SimpleClass {
  SimpleClass();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return
}
以16进制文件打开生成的class文件如下:



 
 
 

 

魔数(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

 

 

  • 大小: 9 KB
0
0
分享到:
评论

相关推荐

    java字节码文件查看工具,查看class文件

    Java字节码文件查看工具,如JD-GUI,是开发者们深入理解Java应用程序内部机制的重要辅助工具。这类工具能够帮助我们查看并分析.class文件,这些文件是Java源代码经过编译后的二进制形式,包含了运行时所需的所有指令...

    class运行器v6(可以运行java字节码文件的工具 含代码)

    标题中的“class运行器v6”是一个用于执行Java字节码文件的应用程序,它允许用户在没有完整Java环境的情况下运行单个.class文件。这个工具可能是由开发者为了方便测试或教学目的而创建的,特别是对于那些不熟悉或者...

    从一个class文件深入理解Java字节码结构

    【Java字节码结构解析】 Java程序在执行时,首先需要通过Java编译器将源代码(.java文件)编译成二进制的字节码文件(.class文件),这些字节码由Java虚拟机(JVM)解析并执行。深入理解字节码结构有助于我们了解...

    class文件结构解析字节码后文件

    class文件结构解析字节码后文件

    java字节码分析工具

    Java字节码分析工具,系统分析了java字节码文件,即java class类文件,对该文件中的各种成分以树的形式描述出来,只能针对未加密的class文件,一般由标准java编译器编译生成的class文件都未加密,该系统在vs2003下面...

    Java字节码(.class文件)格式详解((转载)

    `.docx`文档可能详细解析了Java字节码中的各个指令,包括它们的编码、含义、操作数和实际应用。通过阅读这份文档,你可以深入理解JVM如何执行字节码,以及如何通过反编译工具如jad、 jclasslib来分析`.class`文件。 ...

    java字节码编辑器

    Java字节码编辑器是一种工具,它允许开发者直接编辑Java程序编译后的`.class`文件,而不是反编译后再重新编译。这种编辑器对于理解、调试和优化Java代码非常有用,尤其是对于那些无法访问源代码或者需要进行底层操作...

    java解析class文件

    在实际开发中,解析Class文件的工具和库有很多,如javap(Java字节码反汇编器)、ASM、BCEL、Javassist等。这些工具可以帮助开发者深入理解字节码,甚至自动生成或修改字节码,实现一些高级功能。 总而言之,Java...

    java字节码文件反编译

    Java字节码文件反编译是一项重要的技术,它允许开发者查看和理解已编译的Java类文件(.class文件)内部的源代码结构。在Java中,源代码被编译成字节码,这是一种中间语言,由Java虚拟机(JVM)执行。然而,有时我们...

    Java字节码优化框架

    Java字节码优化框架,如Soot,是用于提升Java程序性能的重要工具。Soot作为一个独立的工具,能够对Java字节码进行优化和检查,同时也为开发者提供了一个框架,以便于在字节码级别设计和实现优化策略。这个框架支持...

    借助jclasslib与javassist修改java class字节码

    `jclasslib`则是一款图形化的Java字节码浏览器,主要用于解析和展示Java字节码文件(`.class`文件)的内容。它可以直观地显示字节码指令和常量池中的信息,并且提供了一定程度上的编辑功能,使得用户可以直接在图形...

    cpp-C语言实现的一个解析JAVAclass字节码的库

    C++库解析Java字节码的主要目的是为了能够读取、分析或者修改Class文件的结构。这在逆向工程、性能优化、安全分析以及跨语言集成等场景中非常有用。例如,开发者可能需要知道类的结构、方法签名、常量池信息,或者对...

    java class文件解析

    1. **Java字节码**:Java源代码编译后生成的是.class文件,其中存储的就是字节码,这是一种中间表示,与具体的硬件平台无关。每条字节码指令占用一个字节,由操作码和操作数组成,用于JVM执行。 2. **类文件结构**...

    修改class字节码需要的工具.zip

    1. **Luyten 0.5.4**: 这是一个跨平台的Java字节码查看器和编辑器,可以帮助开发者查看并修改`.class`文件。Luyten提供了图形化的界面,使得字节码的分析和修改变得更加直观。你可以通过加载`.class`文件,查看其...

    Android-Java代码解析class文件

    1. **Java字节码结构**: - 类文件以魔数`CAFEBABE`开头,用于识别文件格式。 - 接着是版本信息,包括字节码版本号和常量池计数器。 - 常量池是类文件的核心部分,包含字符串、类名、方法名、字段名等各种常量。 ...

    python实现的简单的class解析以及简单执行class.zip

    Python是一种强大的、动态...它需要对Java字节码格式有深入的理解,同时也需要熟悉Python的字节操作和数据结构。通过实践这样的项目,开发者可以增强跨语言编程的能力,同时也能对Java和Python的底层机制有更深的认识。

    java字节码反编译工具

    Java字节码反编译工具是开发者们在研究或调试Java程序时常用的一种辅助软件,它能够将已编译的Java字节码(.class文件)转换回可读性较高的源代码形式。这样的工具使得开发者可以查看和理解第三方库或者无法获取源代码...

    JAVA字节码操作库 BCEL

    **JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...

Global site tag (gtag.js) - Google Analytics