使用JVM的HSDIS插件对java代码进行反汇编

假设要对下面代码进行反汇编:

package org.example.volatiletest;

public class VolatileTest {

    public  static volatile  boolean stop = false;
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            int i = 0;
            while (!stop){
                i++;
            }
        });
        t.start();
        System.out.println("start thread.");
        Thread.sleep(1000);
        stop = true;
    }
}

需要将编译好的 插件hsdis-amd64.lib hsdis-amd64.dll放到 C:\Program Files\Java\jdk1.8.0_181\jre\bin\server 路径下(实际路径根据自己安装路径修改)
在这里插入图片描述
然后在idea中配置jvm参数: VolatileTest 是要反汇编的类的名字(如果要反汇编具体的某个方法,类名后面加上.方法名) 并且需要指定安装了插件的jre的路径,如下图所示:

-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly  -XX:CompileCommand=compileonly,*VolatileTest.* 

在这里插入图片描述

注意是Java\jdk1.8.0_181\jre\bin\server 路径,而不是 C:\Program Files\Java\jre1.8.0_181\bin\server, 我就是因为路径配置错了,一直报下面这样的错误提示:
在这里插入图片描述

接下来,运行代码,就可以得到代码对应的汇编语言的代码了,这里只挑出来最关键的一部分,加了volatile关键字后,汇编代码中会在stop变量上加上一个lock指令:
在这里插入图片描述
javap -v 反编译后如下:

Classfile /E:/Baidudownload/JUC/out/production/JUC/org/example/volatiletest/VolatileTest.class
  Last modified 2021-8-14; size 1546 bytes
  MD5 checksum 15f06b76e561d96fbaa0b940f4685186
  Compiled from "VolatileTest.java"
public class org.example.volatiletest.VolatileTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #14.#39        // java/lang/Object."<init>":()V
   #2 = Class              #40            // java/lang/Thread
   #3 = InvokeDynamic      #0:#45         // #0:run:()Ljava/lang/Runnable;
   #4 = Methodref          #2.#46         // java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
   #5 = Methodref          #2.#47         // java/lang/Thread.start:()V
   #6 = Fieldref           #48.#49        // java/lang/System.out:Ljava/io/PrintStream;
   #7 = String             #50            // start thread.
   #8 = Methodref          #51.#52        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #9 = Long               1000l
  #11 = Methodref          #2.#53         // java/lang/Thread.sleep:(J)V
  #12 = Fieldref           #13.#54        // org/example/volatiletest/VolatileTest.stop:Z
  #13 = Class              #55            // org/example/volatiletest/VolatileTest
  #14 = Class              #56            // java/lang/Object
  #15 = Utf8               stop
  #16 = Utf8               Z
  #17 = Utf8               <init>
  #18 = Utf8               ()V
  #19 = Utf8               Code
  #20 = Utf8               LineNumberTable
  #21 = Utf8               LocalVariableTable
  #22 = Utf8               this
  #23 = Utf8               Lorg/example/volatiletest/VolatileTest;
  #24 = Utf8               main
  #25 = Utf8               ([Ljava/lang/String;)V
  #26 = Utf8               args
  #27 = Utf8               [Ljava/lang/String;
  #28 = Utf8               t
  #29 = Utf8               Ljava/lang/Thread;
  #30 = Utf8               Exceptions
  #31 = Class              #57            // java/lang/InterruptedException
  #32 = Utf8               lambda$main$0
  #33 = Utf8               i
  #34 = Utf8               I
  #35 = Utf8               StackMapTable
  #36 = Utf8               <clinit>
  #37 = Utf8               SourceFile
  #38 = Utf8               VolatileTest.java
  #39 = NameAndType        #17:#18        // "<init>":()V
  #40 = Utf8               java/lang/Thread
  #41 = Utf8               BootstrapMethods
  #42 = MethodHandle       #6:#58         // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #43 = MethodType         #18            //  ()V
  #44 = MethodHandle       #6:#59         // invokestatic org/example/volatiletest/VolatileTest.lambda$main$0:()V
  #45 = NameAndType        #60:#61        // run:()Ljava/lang/Runnable;
  #46 = NameAndType        #17:#62        // "<init>":(Ljava/lang/Runnable;)V
  #47 = NameAndType        #63:#18        // start:()V
  #48 = Class              #64            // java/lang/System
  #49 = NameAndType        #65:#66        // out:Ljava/io/PrintStream;
  #50 = Utf8               start thread.
  #51 = Class              #67            // java/io/PrintStream
  #52 = NameAndType        #68:#69        // println:(Ljava/lang/String;)V
  #53 = NameAndType        #70:#71        // sleep:(J)V
  #54 = NameAndType        #15:#16        // stop:Z
  #55 = Utf8               org/example/volatiletest/VolatileTest
  #56 = Utf8               java/lang/Object
  #57 = Utf8               java/lang/InterruptedException
  #58 = Methodref          #72.#73        // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #59 = Methodref          #13.#74        // org/example/volatiletest/VolatileTest.lambda$main$0:()V
  #60 = Utf8               run
  #61 = Utf8               ()Ljava/lang/Runnable;
  #62 = Utf8               (Ljava/lang/Runnable;)V
  #63 = Utf8               start
  #64 = Utf8               java/lang/System
  #65 = Utf8               out
  #66 = Utf8               Ljava/io/PrintStream;
  #67 = Utf8               java/io/PrintStream
  #68 = Utf8               println
  #69 = Utf8               (Ljava/lang/String;)V
  #70 = Utf8               sleep
  #71 = Utf8               (J)V
  #72 = Class              #75            // java/lang/invoke/LambdaMetafactory
  #73 = NameAndType        #76:#80        // metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #74 = NameAndType        #32:#18        // lambda$main$0:()V
  #75 = Utf8               java/lang/invoke/LambdaMetafactory
  #76 = Utf8               metafactory
  #77 = Class              #82            // java/lang/invoke/MethodHandles$Lookup
  #78 = Utf8               Lookup
  #79 = Utf8               InnerClasses
  #80 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  #81 = Class              #83            // java/lang/invoke/MethodHandles
  #82 = Utf8               java/lang/invoke/MethodHandles$Lookup
  #83 = Utf8               java/lang/invoke/MethodHandles
{
  public static volatile boolean stop;
    descriptor: Z
    flags: ACC_PUBLIC, ACC_STATIC, ACC_VOLATILE

  public org.example.volatiletest.VolatileTest();
    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
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lorg/example/volatiletest/VolatileTest;

  public static void main(java.lang.String[]) throws java.lang.InterruptedException;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=2, args_size=1
         0: new           #2                  // class java/lang/Thread
         3: dup
         4: invokedynamic #3,  0              // InvokeDynamic #0:run:()Ljava/lang/Runnable;
         9: invokespecial #4                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
        12: astore_1
        13: aload_1
        14: invokevirtual #5                  // Method java/lang/Thread.start:()V
        17: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        20: ldc           #7                  // String start thread.
        22: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        25: ldc2_w        #9                  // long 1000l
        28: invokestatic  #11                 // Method java/lang/Thread.sleep:(J)V
        31: iconst_1
        32: putstatic     #12                 // Field stop:Z
        35: return
      LineNumberTable:
        line 6: 0
        line 12: 13
        line 13: 17
        line 14: 25
        line 15: 31
        line 16: 35
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      36     0  args   [Ljava/lang/String;
           13      23     1     t   Ljava/lang/Thread;
    Exceptions:
      throws java.lang.InterruptedException

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: iconst_0
         1: putstatic     #12                 // Field stop:Z
         4: return
      LineNumberTable:
        line 4: 0
}
SourceFile: "VolatileTest.java"
InnerClasses:
     public static final #78= #77 of #81; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
  0: #42 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #43 ()V
      #44 invokestatic org/example/volatiletest/VolatileTest.lambda$main$0:()V
      #43 ()V

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值