Java源文件反编译成汇编语言:1.javac编译Java源文件为.class文件,2.javap反编译.class文件成汇编语言;.class文件结构

Java源文件反编译成汇编语言

1.javac将Java源文件编译为.class文件

示例:

public class MyClass {
    public static final int MAX_SIZE = 100;
    public static final String HELLO = "Hello, World!";
}

.class 文件中的静态常量池会包含:

  • 整数常量 100,对应 MAX_SIZE
  • 字符串常量 "Hello, World!",对应 HELLO

打开存放该Java源文件的目录,进入dos窗口,执行命令,在当前目录生成对应的 .class 文件

javac .\文件名

在这里插入图片描述
使用notepad查看编译后的.class文件,需要安装进制转换插件
在这里插入图片描述
安装之后会重启notepad,重启完成选中进制转换
在这里插入图片描述
可以看到字节码文件格式化后是以16进制展示的,它的本质是二进制文件,里面存放的是16进制的字节元,以16进制展示的

2.javap将.class文件反编译成汇编语言

.class文件本质是二进制文件,看起来很难受,因此Java提供了反编译技术,可以将对应的.class文件反编译成汇编语言,方便我们阅读。

在当前字节码文件目录执行命,将对应的.class文件反编译成汇编语言,并输出为.txt文件

javap -p -v .\MyClass.class >MyClass.txt

命令参数解释:

  • -p:选项告诉 javap 显示类的所有成员,包括私有(private)、受保护(protected)、包级(default)和公共(public)成员。默认情况下,javap 只显示公共成员,通过使用 -p 选项,可以查看所有成员,无论它们的访问修饰符是什么。
    • 使用示例:
      javap -p MyClass
      
      这将列出 MyClass 类的所有成员,包括 private、protected、default 和 public 字段及方法。
  • -v:选项告诉 javap 显示详细的字节码信息。这包括常量池、字段的签名、方法的字节码、局部变量表等详细信息。它通常用于深入分析类文件的结构和字节码指令。
    • 使用示例:
      这将输出 MyClass 类的详细信息,包括类的字节码、常量池内容、字段、方法、签名、方法的字节码指令等。
  • 组合使用:当 -p 和 -v 一起使用时,命令将显示类的所有成员(包括私有成员)以及详细的字节码信息。这个组合命令通常用于对类进行深入分析,查看其完整的结构和编译后的指令。
    • 使用示例:
      javap -p -v MyClass
      
    • 输出结果将包括:
      • 类的所有字段(包括私有字段)
      • 类的所有方法(包括私有方法)
      • 常量池信息
      • 字节码指令
      • 局部变量表
      • 其他编译相关的信息

在这里插入图片描述
.txt文件内容如下:

Classfile /D:/IdeaProjects/SutureMonster/sm-demo/src/main/java/com/sm/demo/Test/MyClass.class
  Last modified 2024年12月16日; size 321 bytes
  SHA-256 checksum cb02fe5b46f39d36c5ea75b334426df02c51e075ef95b2883de59c7b2de60779
  Compiled from "MyClass.java"
public class com.sm.demo.Test.MyClass
  minor version: 0
  major version: 65
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #7                          // com/sm/demo/Test/MyClass
  super_class: #2                         // java/lang/Object
  interfaces: 0, fields: 2, methods: 1, attributes: 1
Constant pool:
   #1 = Methodref          #2.#3          // java/lang/Object."<init>":()V
   #2 = Class              #4             // java/lang/Object
   #3 = NameAndType        #5:#6          // "<init>":()V
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Class              #8             // com/sm/demo/Test/MyClass
   #8 = Utf8               com/sm/demo/Test/MyClass
   #9 = Utf8               MAX_SIZE
  #10 = Utf8               I
  #11 = Utf8               ConstantValue
  #12 = Integer            100
  #13 = Utf8               HELLO
  #14 = Utf8               Ljava/lang/String;
  #15 = String             #16            // Hello, World!
  #16 = Utf8               Hello, World!
  #17 = Utf8               Code
  #18 = Utf8               LineNumberTable
  #19 = Utf8               SourceFile
  #20 = Utf8               MyClass.java
{
  public static final int MAX_SIZE;
    descriptor: I
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: int 100

  public static final java.lang.String HELLO;
    descriptor: Ljava/lang/String;
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: String Hello, World!

  public com.sm.demo.Test.MyClass();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
}
SourceFile: "MyClass.java"

.class文件结构

ClassFile结构官网描述

ClassFile {
    u4             magic;//字节码文件的规范,一般value是以0xCAFEBABE开头,俗称为魔术开头
    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];
}

u2,u4,u8是无符号数据类型,是2的n次方。

注意:class文件结构里的常量池是指静态常量池
常量池一般分为三类,静态常量池,运行时常量池,字符串常量池。而class文件结构这里说的常量池指的是静态常量池。

静态常量池当中存放两个东西:

  1. 字面量:文本;字符串;final修饰的(final修饰的不一定都为常量)
  2. 符号引用:类、接口、字段、方法的一些描述信息

constant_pool是一个结构表,表示在结构及其子结构中引用的各种字符串常量、类和接口名称、字段名称和其他常量。每个表项的格式由其第一个“标记”字节表示。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐