Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

JuneLeo/class-parse

Open more actions menu

Repository files navigation

class-parse

Parse

parse

每个颜色代表一种解析器

code table

parse

Constant Pool

类型 字段 描述
CONSTANT_Utf8_info tag/length/bytes(u1) UTF-8字符串
CONSTANT_Integer_info tag/bytes(u4) int
CONSTANT_Float_info tag/bytes(u4) float
CONSTANT_Long_info tag/bytes(u8) long
CONSTANT_Double_info tag/bytes(u8) double
CONSTANT_Class_info tag/index 类或者接口符号引用
CONSTANT_String_info tag/index 字符串类型字面量
CONSTANT_Fieldref_info tag/index类/index 字段符号引用
CONSTANT_Methodref_info tag/index类/index 类中方法符号引用
CONSTANT_Interface-Methodref_info tag/index接口类/index 接口中方法符号引用
CONSTANT_NameAndType_info tag/index名称/index签名 字段或者方法的部分符号引用
CONSTANT_Method-Handle_info 方法句柄
CONSTANT_Method-type_info 标识方法类型
CONSTANT_Invoke-Dynamic_info 动态方法调用点

Attribute

类型 描述
Code 方法表
LineNumberTable 调试表
LocalVariableTable 本地变量表
SourceFile 源文件表
Exceptions 异常表
ConstantValue 异常表
InnerClasses 内部类表
Deprecated 废弃标识
Synthetic 表示方法或者字段
StackMapTable 类型检查器
Signature 泛型的方法签名 - 泛型会类型擦除
BootstrapMethods invokedymic相关
LocalVariableTypeTable 泛型相关
还有很多其他未解析的表

Example

  • Person
public class Person {
    public String name;
    public int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void play(String name) {
        if (name.equals("basket")) {
            System.out.println("篮球");
        }

    }
}
  • Person 解析
magic: CAFEBABE
minor: 0
major: 52
Constant pool: 
    #1 = [ name=CONSTANT_Methodref_info, classIndex=10, nameAndTypeIndex=27 ]
    #2 = [ name=CONSTANT_Fieldref_info, classIndex=9, nameAndTypeIndex=28 ]
    #3 = [ name=CONSTANT_Fieldref_info, classIndex=9, nameAndTypeIndex=29 ]
    #4 = [ name=CONSTANT_String_info, index=30 ]
    #5 = [ name=CONSTANT_Methodref_info, classIndex=31, nameAndTypeIndex=32 ]
    #6 = [ name=CONSTANT_Fieldref_info, classIndex=33, nameAndTypeIndex=34 ]
    #7 = [ name=CONSTANT_String_info, index=35 ]
    #8 = [ name=CONSTANT_Methodref_info, classIndex=36, nameAndTypeIndex=37 ]
    #9 = [ name=CONSTANT_Class_info, index=38 ]
    #10 = [ name=CONSTANT_Class_info, index=39 ]
    #11 = [ name=CONSTANT_Utf8_info, length=4, value='name ]
    #12 = [ name=CONSTANT_Utf8_info, length=18, value='Ljava/lang/String; ]
    #13 = [ name=CONSTANT_Utf8_info, length=3, value='age ]
    #14 = [ name=CONSTANT_Utf8_info, length=1, value='I ]
    #15 = [ name=CONSTANT_Utf8_info, length=6, value='<init> ]
    #16 = [ name=CONSTANT_Utf8_info, length=22, value='(Ljava/lang/String;I)V ]
    #17 = [ name=CONSTANT_Utf8_info, length=4, value='Code ]
    #18 = [ name=CONSTANT_Utf8_info, length=15, value='LineNumberTable ]
    #19 = [ name=CONSTANT_Utf8_info, length=18, value='LocalVariableTable ]
    #20 = [ name=CONSTANT_Utf8_info, length=4, value='this ]
    #21 = [ name=CONSTANT_Utf8_info, length=20, value='Lorg/example/Person; ]
    #22 = [ name=CONSTANT_Utf8_info, length=4, value='play ]
    #23 = [ name=CONSTANT_Utf8_info, length=21, value='(Ljava/lang/String;)V ]
    #24 = [ name=CONSTANT_Utf8_info, length=13, value='StackMapTable ]
    #25 = [ name=CONSTANT_Utf8_info, length=10, value='SourceFile ]
    #26 = [ name=CONSTANT_Utf8_info, length=11, value='Person.java ]
    #27 = [ name=CONSTANT_NameAndType_info, nameIndex=15, signatureIndex=40 ]
    #28 = [ name=CONSTANT_NameAndType_info, nameIndex=11, signatureIndex=12 ]
    #29 = [ name=CONSTANT_NameAndType_info, nameIndex=13, signatureIndex=14 ]
    #30 = [ name=CONSTANT_Utf8_info, length=6, value='basket ]
    #31 = [ name=CONSTANT_Class_info, index=41 ]
    #32 = [ name=CONSTANT_NameAndType_info, nameIndex=42, signatureIndex=43 ]
    #33 = [ name=CONSTANT_Class_info, index=44 ]
    #34 = [ name=CONSTANT_NameAndType_info, nameIndex=45, signatureIndex=46 ]
    #35 = [ name=CONSTANT_Utf8_info, length=6, value='篮球 ]
    #36 = [ name=CONSTANT_Class_info, index=47 ]
    #37 = [ name=CONSTANT_NameAndType_info, nameIndex=48, signatureIndex=23 ]
    #38 = [ name=CONSTANT_Utf8_info, length=18, value='org/example/Person ]
    #39 = [ name=CONSTANT_Utf8_info, length=16, value='java/lang/Object ]
    #40 = [ name=CONSTANT_Utf8_info, length=3, value='()V ]
    #41 = [ name=CONSTANT_Utf8_info, length=16, value='java/lang/String ]
    #42 = [ name=CONSTANT_Utf8_info, length=6, value='equals ]
    #43 = [ name=CONSTANT_Utf8_info, length=21, value='(Ljava/lang/Object;)Z ]
    #44 = [ name=CONSTANT_Utf8_info, length=16, value='java/lang/System ]
    #45 = [ name=CONSTANT_Utf8_info, length=3, value='out ]
    #46 = [ name=CONSTANT_Utf8_info, length=21, value='Ljava/io/PrintStream; ]
    #47 = [ name=CONSTANT_Utf8_info, length=19, value='java/io/PrintStream ]
    #48 = [ name=CONSTANT_Utf8_info, length=7, value='println ]
flags: ACC_PUBLIC,ACC_SUPER
---------------------------------------
flags: ACC_PUBLIC
filed: name
descriptor: Ljava/lang/String;
---------------------------------------
flags: ACC_PUBLIC
filed: age
descriptor: I
---------------------------------------
flags: ACC_PUBLIC
method: <init>
descriptor: (Ljava/lang/String;I)V
Code:
    maxStack=2  maxLocals=3
        0: aload_0
        1: invokespecial java/lang/Object  <init>  ()V
        4: aload_0
        5: aload_1
        6: putfield org/example/Person  name  Ljava/lang/String;
        9: aload_0
        10: iload_2
        11: putfield org/example/Person  age  I
        14: return
LineNumberTable:
    line 8:0
    line 9:4
    line 10:9
    line 11:14
LocalVariableTable:
    Start=0, Length=15, Slot=0, nameIndex=this, descriptorIndex=Lorg/example/Person;
    Start=0, Length=15, Slot=1, nameIndex=name, descriptorIndex=Ljava/lang/String;
    Start=0, Length=15, Slot=2, nameIndex=age, descriptorIndex=I
---------------------------------------
flags: ACC_PUBLIC
method: play
descriptor: (Ljava/lang/String;)V
Code:
    maxStack=2  maxLocals=2
        0: aload_1
        1: ldc basket
        3: invokevirtual java/lang/String  equals  (Ljava/lang/Object;)Z
        6: ifeq name
        9: getstatic java/lang/System  out  Ljava/io/PrintStream;
        12: ldc 篮球
        14: invokevirtual java/io/PrintStream  println  (Ljava/lang/String;)V
        17: return
LineNumberTable:
    line 15:0
    line 16:9
    line 18:17
LocalVariableTable:
    Start=0, Length=18, Slot=0, nameIndex=this, descriptorIndex=Lorg/example/Person;
    Start=0, Length=18, Slot=1, nameIndex=name, descriptorIndex=Ljava/lang/String;
StackMapTable:
    frame_type=17
---------------------------------------
SourceFile: 
    Person.java

解析接口

public interface Parse {
    int parse(int start, byte[] code);
}
  • code:为class字节码
  • start:解析器开始解析位置
  • return:下一个解析器开始解析的位置

ClassFormat

public class ClassFormat {
    
    private List<Parse> parses = new ArrayList<>();
    
    public ClassFormat() {
        parses.add(new MagicParse()); //magic解析器
        parses.add(new VersionParse()); // 版本解析器
        parses.add(new ConstantParse()); // 常量池解析器
        parses.add(new AccessFlagParse()); // class access flag解析器
        parses.add(new ClassExtParse());  // class info解析器
        parses.add(new InterfaceParse()); // class的接口解析器
        parses.add(new FieldParse()); // field变量解析器
        parses.add(new MethodParse());   // method方法解析器
        parses.add(new AttributeParse());  // 类的其他属性解析器
    }


    public void parse(byte[] bytes) {
        int start = 0;
        for (Parse pars : parses) {
            start = pars.parse(start, bytes);
        }
    }
}

About

使用java实现一个class字节码解析工具

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.