温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java如何拆解字节码文件

发布时间:2022-02-19 16:01:13 来源:亿速云 阅读:117 作者:iii 栏目:开发技术

这篇文章主要讲解了“java如何拆解字节码文件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java如何拆解字节码文件”吧!

源代码

public class test {
    private static int classV =2;
    public static void main(String[] args) {
        classV =200;
        int localV =4;
        localV =400;
    }
}

javap 指令和选项

0:无选项

打印package, protected and public fields, and methods 
public class com.example.test {
  public com.example.test();
  public static void main(java.lang.String[]);
  static {};
}

1:辅助指令


-help
–help
-?

2:代码行号和方法的局部变量表

-l

public class com.example.test {

  //默认构造方法
  public com.example.test();
   //代码行号:命令偏移位置
    LineNumberTable:
      line 3: 0
   //局部变量表
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0       5     0  this   Lcom/example/test;

  public static void main(java.lang.String[]);
  //代码行号:命令偏移位置
    LineNumberTable:
      line 6: 0
      line 7: 6
      line 8: 8
      line 9: 12
    //局部变量表
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      13     0  args   [Ljava/lang/String; //方法参数
          8       5     1 localV   I。/局部变量localV

	//静态代码块
  static {};
    LineNumberTable:
      line 4: 0
}

3 用级别过滤方法 属性 类


-public
-protected
-private
-p

4.反汇编 出汇编指令

javap -c

//纯汇编指令
public class com.example.test {
  public com.example.test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: sipush        200
       3: putstatic     #2                  // Field classV:I
       6: iconst_4
       7: istore_1
       8: sipush        400
      11: istore_1
      12: return

  static {};
    Code:
       0: iconst_2
       1: putstatic     #2                  // Field classV:I
       4: return
}

5 显示verbose详细信息

javap -v

Classfile /Users/zhangshanxue/Downloads/akka-quickstart-java/target/classes/com/example/test.class
//javap -sysinfo显示下面3行
  Last modified 2021-4-5; size 507 bytes
  MD5 checksum 24a0c74751aafd61d0f7f69be9c161db
  Compiled from "test.java"
public class com.example.test
//即1.8 对照表和原因见附录1 
//u2类型 即每个占用两个字节
  minor version: 0
  major version: 52  
  //类标志 见附录2 
  //u2类型access_flags 通过位与表示多个权限 
  flags: ACC_PUBLIC, ACC_SUPER 
//常量池。class文件结构重点  
//u2 2两个字节 表示数量
//pool 常量池
//constant_pool_count 和constant_pool[]表示为常量池中内容
//后面大部分内容依赖此常量池
Constant pool:
   #1 = Methodref          #4.#22         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#23         // com/example/test.classV:I
   #3 = Class              #24            // com/example/test
   #4 = Class              #25            // java/lang/Object
   #5 = Utf8               classV
   #6 = Utf8               I
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/example/test;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               localV
  #19 = Utf8               <clinit>
  #20 = Utf8               SourceFile
  #21 = Utf8               test.java
  #22 = NameAndType        #7:#8          // "<init>":()V
  #23 = NameAndType        #5:#6          // classV:I
  #24 = Utf8               com/example/test
  #25 = Utf8               java/lang/Object
{
  public com.example.test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      //代码汇编指令
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
         //Javap -l显示下面信息
          //行号和上面对应的指令偏移位置      
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
      	//局部变量表 在指令偏移位置start start+length之间有效
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/example/test;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
     //代码汇编指令     
      stack=1, locals=2, args_size=1
         0: sipush        200
         3: putstatic     #2                  // Field classV:I
         6: iconst_4
         7: istore_1
         8: sipush        400
        11: istore_1
        12: return
         //Javap -l显示下面信息
         //行号和上面对应的指令偏移位置
      LineNumberTable:
        line 6: 0
        line 7: 6
        line 8: 8
        line 9: 12
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      13     0  args   [Ljava/lang/String;
            8       5     1 localV   I

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: iconst_2
         1: putstatic     #2                  // Field classV:I
         4: return
          //行号和上面对应的指令偏移位置
        LineNumberTable:
        line 4: 0

直接分析字节码块

1为了方便交流表达class文件的结构

使用u1 u2 u4 u8无符号数表示字节数使用*_info 结尾表示池(数组cp_info、field_info、method_info、attribute_info

ClassFile {    
//表示java class的文件格式  固定为cafe baby 4个字节
	u4             magic;    
//主版本号和次版本号共同决定了类文件格式的版本
//u2类型 即每个占用两个字节
//56包含56以后support for N.0 and N.65535 
	u2             minor_version;    
//主版本号56(java12)之前 minjor只支持0  
	u2             major_version;    
//常量池数量
	u2             constant_pool_count;    
	cp_info        constant_pool[constant_pool_count-1];    
	u2             access_flags;    
//this_class、super_class、interfaces指向常量池的CONSTANT_Class_info
	u2             this_class;    
	u2             super_class;    
	u2             interfaces_count;    
	u2             interfaces[interfaces_count];    
	u2             fields_count;    
//指向常量池structures:CONSTANT_Fieldref_info 结构
	field_info     fields[fields_count];    
	u2             methods_count;    
//指向常量池CONSTANT_Methodref_info 结构
	method_info    methods[methods_count];    
	u2             attributes_count;    
	attribute_info attributes[attributes_count];
}

感谢各位的阅读,以上就是“java如何拆解字节码文件”的内容了,经过本文的学习后,相信大家对java如何拆解字节码文件这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI