Java文件编译与反编译(二):class文件解析

本文以文章《Java文件编译与反编译(一):javac命令和javap命令》为基础,进行深入分析

为了方便查看,此处将Test.class文件内容,进行如下调整:

cafebabe0000003400130a0004000f09000300100700110700120100016d010001490100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c65010003696e6301000328294901000a536f7572636546696c65010009546573742e6a6176610c000700080c00050006010004546573740100106a6176612f6c616e672f4f626a6563740021000300040000000100020005000600000002000100070008000100090000001d00010001000000052ab70001b100000001000a000000060001000000010001000b000c000100090000001f00020001000000072ab400020460ac00000001000a00000006000100000004000100 0d00 0000 0200 0e

Class类文件结构中的【表】:

注:本文解析将会按照该表顺序进行。

magic

cafebabe     指魔数

minor_version

00 00   指次版本号

major_version

00 34指主版本号

constant_pool_count

0013对应十进制为:19,表示常量池中有19-1=18项常量

constant_pool

第1项常量: 0a对应十进制为:10代表 Methodref 0004对应十进制为:4指向常量池中声明方法的类描述符的索引项:4 00 0f对应十进制为:15指向常量池中名称及类型描述符的索引项:15第2项常量:09对应十进制为:9代表 Fieldref00 03对应十进制为:3指向常量池中声明字段的类或接口的描述符的索引项:30010对应十进制为:16指向常量池中字段描述符的索引项:16第3项常量:07对应十进制为:7代表 Class0011对应十进制为:17指向全限定名常量项的索引:17第4项常量:07对应十进制为:7代表 Class0012对应十进制为:18指向全限定名常量项的索引:18第5项常量:01对应十进制为:1代表 UTF-80001对应十进制为:1UTF-8编码的字符串占用的字节数为:1 个字节6d对应十进制为:109对应的ASCII值为:m第6项常量:01对应十进制为:1代表 UTF-80001对应十进制为:1UTF-8编码的字符串占用的字节数为: 1个字节49对应十进制为:73对应的ASCII值为:I第7项常量:01对应十进制为:1代表 UTF-80006对应十进制为:6UTF-8编码的字符串占用的字节数为:6 个字节3c 69 6e 69 74 3e对应的ASCII值为:<init>第8项常量:01对应十进制为:1代表 UTF-80003对应十进制为:3UTF-8编码的字符串占用的字节数为: 3个字节28 29 56对应的ASCII值为:()V第9项常量:01对应十进制为:1代表 UTF-80004对应十进制为:4UTF-8编码的字符串占用的字节数为:4 个字节43 6f 64 65对应的ASCII值为:Code第10项常量:01对应十进制为:1代表 UTF-8000f对应十进制为:15UTF-8编码的字符串占用的字节数为: 15个字节4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65对应的ASCII值为:LineNumberTable第11项常量:01对应十进制为:1代表 UTF-80003对应十进制为:3UTF-8编码的字符串占用的字节数为: 3个字节69 6e 63对应的ASCII值为:inc第12项常量:01对应十进制为:1代表 UTF-80003对应十进制为:3UTF-8编码的字符串占用的字节数为: 3个字节28 29 49对应的ASCII值为:()I第13项常量:01对应十进制为:1代表 UTF-8000a对应十进制为:10UTF-8编码的字符串占用的字节数为: 10个字节53 6f 75 72 6365 46 69 6c 65对应的ASCII值为:SourceFile第14项常量:01对应十进制为:1代表 UTF-80009对应十进制为:9UTF-8编码的字符串占用的字节数为:9 个字节54 65 73 74 2e 6a 61 76 61对应的ASCII值为:Test.java

access_flag类或接口的访问标志

00 21指类或接口的访问标志   代表ACC_PUBLIC(标志值0x0001)和ACC_SUPER(标志值0x0020)

this_class

00 03指常量池中类索引项为:3

super_class

00 04指常量池中父类索引项为:4

interfaces_count

00 00指接口计数器值为:0

interfaces

指 接口索引集合(若该类没有实现任何接口,则接口计数器值为0,同时接口索引集合就不占用任何字节)

fields_count

00 01指字段计数器值为:1

fields

指字段表集合

access_flags(u2)

00 02指字段访问标志此值表示:ACC_PRIVATE 字段是否为private

name_index(u2)

00 05指字段的简单名称指向常量池中的索引项:5

descriptor_index(u2)

00 06指字段和方法的描述符指向常量池中的索引项:6

attributes_count(u2)

00 00指属性表计数器值为:0

attributes

指属性表集合

methods_count

00 02指方法计数器值为;2

methods

指字段表集合

access_flags(u2)

00 01指方法访问标志此值表示:ACC_PUBLIC   方法是否为public

name_index(u2)

00 07指方法名称索引指向常量池中的索引项:7

descriptor_index(u2)

00 08指方法描述符索引指向常量池中的索引项:8

attributes_count(u2)

00 01指属性表计数器值为:1

attributes

指属性表集合

attributes_count

00 01指属性表集合大小为:1(表示该类有1个属性)

attributes

指属性表集合

属性表的Code属性:

  • attribute_name_index(u2)

    00 09  指属性名称索引       指向常量池中的索引项:9
  • attribute_length(u4)

    00 00 00 1d  对应十进制为:29指属性值长度(注:属性值的长度固定为整个属性表长度减去6个字节)
  • max_stack(u2)

    00 01 指操作数栈深度的最大值为:1(注:在方法执行的任意时刻,操作数栈都不会超过这个深度)
  • max_locals(u2)

    00 01指局部变量表所需的存储空间为:1(注:单位为Slot)
  • code_length(u4)

    00 00 00 05代表字节码长度为:5
  • code(u1)

    2a b7 00 01 b1用于存储字节码指令的一系列字节流。  解析  2a b7 00 01 b1 的过程:  1. 读入2a,查看虚拟机字节码指令表得0x2a对应的指令为:aload_0,指将第0个Slot中的引用类型的  本地变量本地变量推送到操作数栈顶;  2. 读入 b7 ,查看虚拟机字节码指令表得0xb7对应的指令为:invokespecial,指以操作数栈顶的引用  类型的数据所指向的对象作为方法接收者,调用此对象的实力构造方法、私有方法或父类构造方法;  3.读入 00 01,这是invokespecial的参数,指向常量池中的索引项:1;  4.读入b1,查看虚拟机字节码指令表得0xb1对应的指令为:return,指返回此方法,并且返回值为  void。(这条指令执行后,当前方法结束)
  • exception_table_length(u2)

  • exception_table(exception_info)

  • attributes_count(u2)

  • attributes(attribute_info)


注:ASCII码值对照表

(0)

相关推荐

  • JVM虚拟机Class类文件研究分析

    前言 为了研究Class文件,先编写一个最简单的代码: package com.courage; public class T0100_ByteCode01 { } 之所以说最简单,是因为这个类里面任 ...

  • 初始化

    原文链接http://zhhll.icu/2020/04/29/java%E5%9F%BA%E7%A1%80/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/java%E5% ...

  • 重新认识MySQL中的COUNT语句

    在数据库的增删改查操作中,使用最频繁的就是查询操作. 而在所有查询操作中,统计数量操作更是经常被用到. 关于数据库中行数统计,无论是MySQL还是Oracle亦或者是SqlServer,都有一个函数可 ...

  • Java文件编译与反编译(一):javac命令和javap命令

    Java文件编译与反编译(一):javac命令和javap命令 1.创建一个Test.java文件,并输入内容 public class Test{private int m;public int i ...

  • Java代码的编译与反编译那些事儿

    编程语言 在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language).编程语言(Programming Language)分为低级语言(Low-level Lang ...

  • java~jar防止反编译

    对于jar包,如果是为客户私有化部署的,会将jar包给客户,这时就会有源代码泄露的风险,你的一些加密算法,密钥就公开了,所以我们需要为jar包进行加密,或者叫字节码混淆. classfinal cla ...

  • 几种工具反编译被编译好的DLL文件

    我们平时在工作中经常会遇到一些已经被编译后的DLL,而且更加麻烦是没有源代码可以进行修改,只能针对这个DLL的文件进行修改才能得到我们想要的结果:本文将通过一个实例来演示如果完成一个简单的修改;我们将 ...

  • 破解 APICloud 加密 H5文件,解密 apicloud 资源提取,h5app 反编译成源码

    看代码使用的是APICloud,APP开发的时候本身是不需要写JAVA代码,APICloud封装好了,当然也包括解密的代码.反编译一下就能找到加密解密 的核心算法.apk包里必然有解密的 相应so. ...

  • (6条消息) python文件编译与pyc反编译

    pyc是编译py之后生成的二进制文件.当我们发布系统的时候不想让别人看到源代码,就需要将py文件编译生成pyc文件,对外只提供pyc文件.同样,如果拿到一个python程序,只有pyc文件,我们就无法 ...

  • Java 反编译工具几枚(class转java)

    Java 反编译工具几枚(class转java)

  • Linux系统中编译、链接的基石-ELF文件:扒开它的层层外衣,从字节码的粒度来探索

    初次见面 大家好,我是 ELF 文件,大名叫 Executable and Linkable Format. 经常在 Linux 系统中开发的小伙伴们,对于我肯定是再熟悉不过了,特别是那些需要了解编译 ...

  • Eclipse反编译工具Jad及插件JadClipse配置

    Jad是一个Java的一个反编译工具,是用命令行执行,和通常JDK自带的java,javac命令是一样的.不过因为是控制台运行,所以用起来不太方便.不过幸好有一个eclipse的插件JadClipse ...