.class字节码向BAF码的转换

一个最简单的例子:

.class字节码向BAF码的转换_第1张图片

例子

当经过编译为.class文件时,使用javap -v 的到它的字节码的近汇编码,javap的使用方法看:javap命令简述

得到返汇编后的字节码:

Classfile /home/zhida/soot/test.class

  Last modified 2019-8-9; size 428 bytes

  MD5 checksum d7a1b61cbddf920eda42f6a2c460f0f8

  Compiled from "test.java"

public class test

  SourceFile: "test.java"

  minor version: 0

  major version: 46

  flags: ACC_PUBLIC, ACC_SUPER
Classfile /home/zhida/soot/test.class

  Last modified 2019-8-9; size 428 bytes

  MD5 checksum d7a1b61cbddf920eda42f6a2c460f0f8

  Compiled from "test.java"


public class test

  SourceFile: "test.java"

  minor version: 0

  major version: 46

  flags: ACC_PUBLIC, ACC_SUPER

Constant pool:

  #1 = NameAndType        #23:#26        //  out:Ljava/io/PrintStream;

  #2 = Utf8              ([Ljava/lang/String;)V

  #3 = Utf8              java/lang/Object

  #4 = Utf8              <init>

  #5 = NameAndType        #4:#9          //  "":()V

  #6 = Class              #3            //  java/lang/Object

  #7 = Class              #18            //  java/io/PrintStream

  #8 = Methodref          #7.#25        //  java/io/PrintStream.println:(I)V

  #9 = Utf8              ()V

  #10 = Class              #22            //  java/lang/System

  #11 = Utf8              Code

  #12 = Utf8              main

  #13 = Class              #24            //  test

  #14 = Fieldref          #10.#1        //  java/lang/System.out:Ljava/io/PrintStream;

  #15 = Utf8              SourceFile

  #16 = Utf8              (I)V

  #17 = Utf8              test.java

  #18 = Utf8              java/io/PrintStream

  #19 = Utf8              println

  #20 = Methodref          #6.#5          //  java/lang/Object."":()V

  #21 = Utf8              LineNumberTable

  #22 = Utf8              java/lang/System

  #23 = Utf8              out

  #24 = Utf8              test

  #25 = NameAndType        #19:#16        //  println:(I)V

  #26 = Utf8              Ljava/io/PrintStream;

{

  public static void main(java.lang.String[]);

    flags: ACC_PUBLIC, ACC_STATIC

    Code:

      stack=3, locals=1, args_size=1

        0: getstatic    #14                // Field java/lang/System.out:Ljava/io/PrintStream;

        3: iconst_1     

        4: iconst_2     

        5: iadd         

        6: invokevirtual #8                  // Method java/io/PrintStream.println:(I)V

        9: return       

      LineNumberTable:

        line 6: 0

        line 3: 3

        line 4: 4

        line 5: 5

        line 6: 6

        line 6: 9

  public test();

    flags: ACC_PUBLIC

    Code: LineNumberTable

      stack=1, locals=1, args_size=1

        0: aload_0     

        1: invokespecial #20                // Method java/lang/Object."":()V

        4: return       

      LineNumberTable:

        line 1: 0

        line 1: 0

        line 1: 1

        line 1: 4

      LineNumberTable:

        line 1: 0

        line 1: 1

        line 1: 4

}

转换为BAF时,则先将最前面的那些关于常量池的定义和类与引用的定义给去掉,再将其中的无用解释码给去掉(就是 LineNumberTable,和局部变量表这种)仅仅保留反汇编码:
得到

public static void main(java.lang.String[]);

    flags: ACC_PUBLIC, ACC_STATIC

    Code:

      stack=3, locals=1, args_size=1

         0: getstatic     #14                 // Field java/lang/System.out:Ljava/io/PrintStream;

         3: iconst_1     

         4: iconst_2     

         5: iadd         

         6: invokevirtual #8                  // Method java/io/PrintStream.println:(I)V

         9: return       


public test();

    flags: ACC_PUBLIC

    Code: LineNumberTable

      stack=1, locals=1, args_size=1

         0: aload_0      

         1: invokespecial #20                 // Method java/lang/Object."":()V

         4: return       

可以在进一步简化,得到:

public class test {

  public static void main(java.lang.String[]);

    Code:

      0: getstatic    #14                // Field java/lang/System.out:Ljava/io/PrintStream;

      3: iconst_1           取出声明的int型变量,压入操作数栈

      4: iconst_2           取出声明的int型变量,压入操作数栈

      5: iadd                  从操作数栈中,将操作数取出,进行相加,将结果入栈

      6: invokevirtual #8                  // Method java/io/PrintStream.println:(I)V 

      9: return      赋返回

  public test();

    Code:

      0: aload_0    从本地变量表中引用0的变量值,即this的引用,压入栈中

      1: invokespecial #20                // Method java/lang/Object."":()V

      4: return       

}

然后,经过栈编译器直接转化:

 0: getstatic                   word r0;         r0 := @parameter0: java.lang.String[];

                                      staticget <java.lang.System: java.io.PrizzntStream out>;

  3: iconst_1                   push 1;

  4: iconst_2                   push 2;

  5: iadd                          add.i;

  6: invokevirtual #8        virtualinvoke <java.io.PrintStream: void println(int)>;

  9: return                       return;

将对test类对象初始化,转换为()

  0: aload_0                    word r0;

                                      r0 := @this: test;  load.r r0;

 1: invokespecial #20     specialinvoke <java.lang.Object: void <init>()>;

 4: return                        return;

得到BAF文件:

.class字节码向BAF码的转换_第2张图片

.baf

你可能感兴趣的:(.class字节码向BAF码的转换)