拆解class字节码文件

JVM四大块

  • 字节码文件
  • 类加载过程
  • 运行时数据区
  • 执行引擎

目的拆解分析反编译字节码 解析成人能够理解的结构 ,然后再对字节码文件进一步分析

源代码

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

二进制
idea bin_ed插件查看。

在这里插入图片描述
看不懂 那就使用人能看的懂的汇编语言查看类文件结构和代码指令。

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[]表示为常量池中内容
//后面大部分内容依赖此常量池

//先阅读下附录5  然后根据反编译的信息 先直接解析下下面的类型
Constant pool:
   #1 = Methodref          #4.#22         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#23         // com/example/test.classV:I
   //this class
   #3 = Class              #24            // com/example/test
   //super class
   #4 = Class              #25            // java/lang/Object
   #5 = Utf8               classV
   #6 = Utf8               I
   #7 = Utf8               <init>
   //MethodDescriptor 经典方法描述符  ({fieldType})ReturnDescription    方法1
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/example/test;
  #14 = Utf8               main
   //MethodDescriptor 经典方法描述符  ({fieldType})ReturnDescription  方法2
  #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

1.1从45开始因为正式发布之前可能 其他版本号可能已经被用了
1.5改为5.0 也是差不多原因 为了表示重要性更名
在这里插入图片描述
Corresponding major version 指定版本 和"Supported major versions"兼容范围

附录2
在这里插入图片描述

附录3直接分析字节码块

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 然后在执行常量池的String结构类型 描述权限定名 j
//这三项确定类的继承关系
	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];
}

附录4常量池字节码结构和常量池结构部分对应关系

在这里插入图片描述
不同版本新增的常量池内容
8 常量池有18种   16有20种

附录5 反编译后filed和class类型描述所表示的类型 class反编译后自己的语法描述语法

类型解释
在这里插入图片描述

方法描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
拆解XML文件,你可以使用Python中的xml.etree.ElementTree模块。这个模块提供了一种简单的方式来解析和操作XML数据。你可以使用ElementTree的parse函数来解析XML文件,并使用相关的方法来获取和操作XML元素。 下面是一个示例代码,展示了如何使用ElementTree来拆解XML文件: ```python import xml.etree.ElementTree as ET # 解析XML文件 tree = ET.parse('your_xml_file.xml') # 获取根元素 root = tree.getroot() # 遍历XML文件中的元素 for child in root: # 在这里可以对每个元素进行操作 # 例如获取元素的标签名和属性值 tag = child.tag attributes = child.attrib # 进一步处理元素的子元素 for sub_child in child: # 在这里可以对子元素进行操作 # 例如获取子元素的文本内容 text = sub_child.text # 可以根据需要进行其他操作,例如保存数据或进行其他处理 ``` 你可以根据自己的需求,进一步处理XML文件中的元素和数据。希望这个示例能帮助到你。 #### 引用[.reference_title] - *1* [python:实现xls文件转xml文件(附完整源码)](https://blog.csdn.net/it_xiangqiang/article/details/129695199)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [如何用Python读取xml文件后,裁剪标注图片和扩容数据](https://blog.csdn.net/weixin_42500684/article/details/113689179)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值