美文网首页
.class字节码向BAF码的转换

.class字节码向BAF码的转换

作者: 转身一世铅华尽 | 来源:发表于2019-08-12 10:26 被阅读0次

    一个最简单的例子:

    例子

    当经过编译为.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

    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          //  "<init>":()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."<init>":()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."<init>":()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."<init>":()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."<init>":()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类对象初始化,转换为<init>()

      0: aload_0                    word r0;

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

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

     4: return                        return;

    ```

    得到BAF文件:

    .baf

    相关文章

      网友评论

          本文标题:.class字节码向BAF码的转换

          本文链接:https://www.haomeiwen.com/subject/dojyjctx.html