`
lobin
  • 浏览: 383297 次
  • 性别: 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
分享到:
评论

相关推荐

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

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

    java字节码分析工具

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

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

    我们都知道,Java程序最终是转换成class文件执行在虚拟机上的,那么class文件是个怎样的结构,虚拟机又是如何处理去执行class文件里面的内容呢,这篇文章带你深入理解Java字节码中的结构。 1.Demo源码 首先,编写一...

    Java字节码操纵框架 asm-3.1组件包大集合

    Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...

    JavaClassViewer-2.0.4_理解class文件结构

    JavaClassViewer-2.0.4, 用于理解Class文件结构。 解析出class结构,以及十六进制的表示,特别方便。 原下载地址: http://www.softpedia.com/get/Programming/File-Editors/Java-Class-Viewer.shtml。另外也可以参考...

    java解析txt

    * 2:获得文件句柄当做是输入一个字节码流,需要对这个输入流进行读取 * 3:读取到输入流后,需要读取生成字节流 * 4:一行一行的输出。readline()。 * 备注:需要考虑的是异常情况 * @param filePath */...

    class文件解析

    一个解析java class文件的代码

    Java虚拟机字节码.zip

    详细介绍ASM框架的API、Class文件结构解析、HotSpot虚拟机类加载源码分析、动态代理与字节码插桩的实现。

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

    a library written by c language,for parsing the standard java class byte codes

    JavaBytecodeAnalyzer:解析学习 Java 字节码

    JavaBytecodeAnalyzer 解析 Java 字节码,学习字节码指令集 解析 class 文件为字节码,以熟悉 class 文件结构 学习 java bytecode 指令集

    asm操作指南(中文)

    ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class...

    asm4-guide.pdf

    Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...

    Java反编译

    Java反编译工具,解析class字节码文件。 解析class字节码文件

    ASM4中文使用指南.zip

    Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...

    pyjvm:在Nintendo Switch上运行Java字节码(.class文件)!

    如果您只想运行已编译的字节码,则只需一个Python解释器。 运行测试 该项目带有许多单元测试。 如果运行shell脚本test.sh ,它将在示例目录中编译Java文件并运行单元测试。 您将能够看到通过了多少测试以及失败了...

    asm-9.0.jar

    ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class文件...

    字节码解析01.rar

    使用Java编程语言,对.class文件进行解析,类似于javap -v filename指令的效果,但是没有对attibutes属性进行解析,需要学习的可以下载,程序运行的效果在本人的博客的附录中

    JAVA程序设计判断题题库81道

    4. Java字节码程序是可以在Java虚拟机上执行的。( ) 答案:√ [考点范围] JAVA简介 5. Java程序对计算机硬件平台的依赖性很低。( ) 答案:√ [考点范围] JAVA简介 6. Java可以用来进行多媒体及网络编程。( ) ...

    asm 最新版手册

    Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...

    asm4.1 jar+demo+doc

    Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...

Global site tag (gtag.js) - Google Analytics