java代码转成ASM API代码

250 阅读16分钟

Java/Kotlin 代码转 ASM API 工具指南

目前虽然没有完全自动化的转换工具,但有一些实用工具和方法可以帮助开发者将 Java 或 Kotlin 代码转换为基于 ASM API 的字节码操作代码。以下是常用工具和方法的详细介绍:

1. ASM Bytecode Viewer

安装方法​:

  • 在 Android Studio 或 IntelliJ IDEA 中,通过插件市场搜索"ASM Bytecode Viewer"或"ASM Bytecode Viewer Support Kotlin"
  • 安装完成后,重启 IDE

使用方法​:

  • 右键点击需要转换的 Java 或 Kotlin 文件或方法
  • 选择"ASM Bytecode Viewer"
  • 插件会生成对应的 ASM 字节码操作代码,并显示在一个新的窗口中

特点​:

  • 支持 Java 和 Kotlin
  • 可以直接生成 ASM 的ClassVisitorMethodVisitor代码
  • 适合初学者快速理解和使用 ASM

2. ASMifier

使用方法​:

  1. 编译 Java 或 Kotlin 代码,生成.class文件
  2. 使用以下命令运行ASMifier
java -classpath "asm-all-4.0.jar" org.objectweb.asm.util.ASMifier <path_to_class_file>

其中asm-all-4.0.jar是 ASM 的 JAR 文件,<path_to_class_file>是目标.class文件的路径

特点​:

  • 官方工具,生成的代码准确可靠
  • 适合对字节码有一定了解的开发者

3. JD-GUI

使用方法​:

  1. 下载并安装JD-GUI
  2. 打开 JD-GUI,将.class文件拖入工具中
  3. 查看反编译后的 Java 代码,了解字节码的结构

特点​:

  • 提供直观的字节码反编译视图
  • 可以帮助开发者更好地理解字节码结构
  • 虽然不直接生成 ASM 代码,但可作为辅助分析工具

4. Kotlin Bytecode Viewer

使用方法​:

  1. 在 Android Studio 中选中需要查看的 Kotlin 文件
  2. 点击菜单栏中的 Tools > Kotlin > Show Kotlin Bytecode
  3. 在弹出的字节码窗口中,点击 Decompile 按钮,查看反编译后的 Java 代码

特点​:

  • 内置工具,无需额外安装
  • 支持 Kotlin 代码的字节码查看
  • 适合 Kotlin 开发者快速查看字节码

5. ASM Bytecode Outline

安装方法​:

  • 在 Android Studio 或 IntelliJ IDEA 中,通过插件市场搜索"ASM Bytecode Outline"
  • 安装完成后,重启 IDE

使用方法​:

  1. 右键点击需要转换的文件或方法,选择"Show Bytecode Outline"
  2. 在弹出的窗口中选择"ASMified"标签,查看生成的 ASM 代码

特点​:

  • 提供详细的字节码分析
  • 支持 Java 和 Kotlin
  • 比 ASM Bytecode Viewer 功能更全面

总结

根据你的具体需求,可以选择以下工具:

  • 初学者友好​:ASM Bytecode Viewer
  • 官方工具​:ASMifier
  • 辅助分析​:JD-GUI
  • Kotlin 专用​:Kotlin Bytecode Viewer
  • 功能全面​:ASM Bytecode Outline

这些工具各有侧重,可以根据开发阶段和需求灵活组合使用。

手动转换

手动转换需要你熟悉Java字节码指令和ASM的API规则,步骤如下:

1. 将Java代码编译成字节码

使用javac命令将Java源代码编译成.class文件,例如:

javac YourJavaFile.java
2. 反编译字节码文件

使用javap工具反编译字节码文件,查看对应的助记符指令,例如:

javap -c YourJavaFile.class
3. 根据指令编写ASM代码

下面以一个简单的Java类为例:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

其对应的字节码指令(使用javap -c HelloWorld查看)如下:

Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hello, World!
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

下面是使用ASM API实现相同功能的代码:

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class AsmExample {
    public static byte[] generateClass() {
        // 创建ClassWriter对象,用于生成类的字节码
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        // 定义类的基本信息,这里定义一个名为HelloWorld的公共类,继承自java.lang.Object
        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "HelloWorld", null, "java/lang/Object", null);

        // 定义类的构造方法
        MethodVisitor constructor = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        constructor.visitCode();
        // 加载this引用
        constructor.visitVarInsn(Opcodes.ALOAD, 0);
        // 调用父类的构造方法
        constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        // 返回
        constructor.visitInsn(Opcodes.RETURN);
        constructor.visitMaxs(1, 1);
        constructor.visitEnd();

        // 定义main方法
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
        mv.visitCode();
        // 获取System.out静态字段
        mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        // 加载字符串常量"Hello, World!"
        mv.visitLdcInsn("Hello, World!");
        // 调用PrintStream的println方法
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        // 返回
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();

        // 结束类的生成
        cw.visitEnd();
        return cw.toByteArray();
    }

    public static void main(String[] args) {
        byte[] bytecode = generateClass();
        // 这里可以将bytecode写入文件或加载到JVM中
    }
}

上述代码中:

  • ClassWriter用于生成类的字节码。
  • MethodVisitor用于访问和修改方法体的字节码。
  • Opcodes类提供了JVM操作码的常量。

手动转换对于复杂的代码来说会比较困难,需要对字节码指令有深入的了解。

知名框架中的使用场景举例

TheRouter中使用ASM插入字节码的实战案例:

com.therouter.plugin.AddCodeVisitor中有数个根据采集数据循环插入代码的案例。 asm插入代码的目标类是TheRouterServiceProvideInjecter,我们对比源码,字节码,修改后的字节码。

1、TheRouterServiceProvideInjecter.kt顶层代码

TheRouterServiceProvideInjecter 并非严格意义上的类,而是 Kotlin 文件顶层代码。

函数和属性会被编译到由 @file:JvmName 指定的类里TheRouterServiceProvideInjecter final类。而且都是public static修饰的,方法还多一个final修饰。

// 指定该文件在 Java 中对应的类名
@file:JvmName("TheRouterServiceProvideInjecter")

// 声明该文件所属的包名
package a

import android.content.Context
import androidx.annotation.Keep
import com.therouter.flow.Digraph

/**
 * 标记该类或方法在混淆时不被移除或重命名
 */
@Keep
/**
 * 内部变量,用于标记是否使用 ASM 进行字节码操作
 */
@JvmField
internal var asm = false

/**
 * 该函数可能用于执行特定的初始化或者拦截操作,当前为空实现。
 */
fun trojan() {}

/**
 * 该函数可能用于执行自动注入逻辑,但传入的对象参数未被使用,当前为空实现。
 */
fun autowiredInject(obj: Any?) {}

/**
 * 该函数可能用于添加流程任务,但传入的上下文和有向无环图参数均未被使用,当前为空实现。
 */
fun addFlowTask(context: Context?, digraph: Digraph) {}

/**
 * 该函数可能用于初始化默认的路由映射表,当前为空实现。
 */
fun initDefaultRouteMap() {}
2、TheRouterServiceProvideInjecter.class字节码,javac或者kotlinc阶段产生。

PS hll-wp-therouter-android\router\build\tmp\kotlin-classes\debug\a> javap -p -v TheRouterServiceProvideInjecter.class > xx.txt

Classfile hll-wp-therouter-android/router/build/tmp/kotlin-classes/debug/a/TheRouterServiceProvideInjecter.class
  Last modified 2025年5月14日; size 1497 bytes
  MD5 checksum c763ff556e739f951790ee7db28f96ad
  Compiled from "TheRouterServiceProvideInjecter.kt"
public final class a.TheRouterServiceProvideInjecter
  minor version: 0
  major version: 55
  flags: (0x0031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER
  this_class: #2                          // a/TheRouterServiceProvideInjecter
  super_class: #4                         // java/lang/Object
  interfaces: 0, fields: 1, methods: 5, attributes: 3
Constant pool:
   #1 = Utf8               a/TheRouterServiceProvideInjecter
   #2 = Class              #1             // a/TheRouterServiceProvideInjecter
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             // java/lang/Object
   #5 = Utf8               trojan
   #6 = Utf8               ()V
   #7 = Utf8               autowiredInject
   #8 = Utf8               (Ljava/lang/Object;)V
   #9 = Utf8               Lorg/jetbrains/annotations/Nullable;
  #10 = Utf8               obj
  #11 = Utf8               Ljava/lang/Object;
  #12 = Utf8               addFlowTask
  #13 = Utf8               (Landroid/content/Context;Lcom/therouter/flow/Digraph;)V
  #14 = Utf8               Lorg/jetbrains/annotations/NotNull;
  #15 = Utf8               digraph
  #16 = String             #15            // digraph
  #17 = Utf8               kotlin/jvm/internal/Intrinsics
  #18 = Class              #17            // kotlin/jvm/internal/Intrinsics
  #19 = Utf8               checkNotNullParameter
  #20 = Utf8               (Ljava/lang/Object;Ljava/lang/String;)V
  #21 = NameAndType        #19:#20        // checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
  #22 = Methodref          #18.#21        // kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
  #23 = Utf8               context
  #24 = Utf8               Landroid/content/Context;
  #25 = Utf8               Lcom/therouter/flow/Digraph;
  #26 = Utf8               initDefaultRouteMap
  #27 = Utf8               <clinit>
  #28 = Utf8               asm
  #29 = Utf8               Z
  #30 = Utf8               Landroidx/annotation/Keep;
  #31 = Utf8               Lkotlin/jvm/JvmField;
  #32 = Utf8               Lkotlin/jvm/JvmName;
  #33 = Utf8               name
  #34 = Utf8               TheRouterServiceProvideInjecter
  #35 = Utf8               Lkotlin/Metadata;
  #36 = Utf8               mv
  #37 = Integer            1
  #38 = Integer            9
  #39 = Integer            0
  #40 = Utf8               k
  #41 = Integer            2
  #42 = Utf8               xi
  #43 = Integer            48
  #44 = Utf8               d1
  #45 = Utf8               \u0000$\n\u0000\n\u0002\u0010\u000b\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u001a\u0018\u0010\u0002\u001a\u00020\u00032\b\u0010\u0004\u001a\u0004\u0018\u00010\u00052\u0006\u0010\u0006\u001a\u00020\u0007\u001a\u0010\u0010\b\u001a\u00020\u00032\b\u0010\t\u001a\u0004\u0018\u00010\n\u001a\u0006\u0010\u000b\u001a\u00020\u0003\u001a\u0006\u0010\f\u001a\u00020\u0003"\u0012\u0010\u0000\u001a\u00020\u00018\u0000@\u0000X\u0081\u000e?\u0006\u0002\n\u0000¨\u0006\r
  #46 = Utf8               d2
  #47 = Utf8
  #48 = Utf8               router_debug
  #49 = Utf8               TheRouterServiceProvideInjecter.kt
  #50 = Utf8               RuntimeInvisibleAnnotations
  #51 = Utf8               Code
  #52 = Utf8               LineNumberTable
  #53 = Utf8               LocalVariableTable
  #54 = Utf8               RuntimeInvisibleParameterAnnotations
  #55 = Utf8               SourceFile
  #56 = Utf8               RuntimeVisibleAnnotations
{
  public static boolean asm;
    descriptor: Z
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    RuntimeInvisibleAnnotations:
      0: #30()
        androidx.annotation.Keep
      1: #31()
        kotlin.jvm.JvmField

  public static final void trojan();
    descriptor: ()V
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=0, locals=0, args_size=0
         0: return
      LineNumberTable:
        line 16: 0

  public static final void autowiredInject(java.lang.Object);
    descriptor: (Ljava/lang/Object;)V
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 17: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0   obj   Ljava/lang/Object;
    RuntimeInvisibleParameterAnnotations:
      parameter 0:
        0: #9()
          org.jetbrains.annotations.Nullable

  public static final void addFlowTask(android.content.Context, com.therouter.flow.Digraph);
    descriptor: (Landroid/content/Context;Lcom/therouter/flow/Digraph;)V
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=2, locals=2, args_size=2
         0: aload_1
         1: ldc           #16                 // String digraph
         3: invokestatic  #22                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
         6: return
      LineNumberTable:
        line 18: 6
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0 context   Landroid/content/Context;
            0       7     1 digraph   Lcom/therouter/flow/Digraph;
    RuntimeInvisibleParameterAnnotations:
      parameter 0:
        0: #9()
          org.jetbrains.annotations.Nullable
      parameter 1:
        0: #14()
          org.jetbrains.annotations.NotNull

  public static final void initDefaultRouteMap();
    descriptor: ()V
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=0, locals=0, args_size=0
         0: return
      LineNumberTable:
        line 19: 0

  static {};
    descriptor: ()V
    flags: (0x0008) ACC_STATIC
    Code:
      stack=0, locals=0, args_size=0
         0: return
}
SourceFile: "TheRouterServiceProvideInjecter.kt"
RuntimeVisibleAnnotations:
  0: #35(#36=[I#37,I#38,I#39],#40=I#41,#42=I#43,#44=[s#45],#46=[s#28,s#47,s#12,s#47,s#23,s#24,s#15,s#25,s#7,s#10,s#47,s#26,s#5,s#48])
    kotlin.Metadata(
      mv=[1,9,0]
      k=2
      xi=48
      d1=["\u0000$\n\u0000\n\u0002\u0010\u000b\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u001a\u0018\u0010\u0002\u001a\u00020\u00032\b\u0010\u0004\u001a\u0004\u0018\u00010\u00052\u0006\u0010\u0006\u001a\u00020\u0007\u001a\u0010\u0010\b\u001a\u00020\u00032\b\u0010\t\u001a\u0004\u0018\u00010\n\u001a\u0006\u0010\u000b\u001a\u00020\u0003\u001a\u0006\u0010\f\u001a\u00020\u0003"\u0012\u0010\u0000\u001a\u00020\u00018\u0000@\u0000X\u0081\u000e?\u0006\u0002\n\u0000¨\u0006\r"]
      d2=["asm","","addFlowTask","","context","Landroid/content/Context;","digraph","Lcom/therouter/flow/Digraph;","autowiredInject","obj","","initDefaultRouteMap","trojan","router_debug"]
    )
RuntimeInvisibleAnnotations:
  0: #32(#33=s#34)
    kotlin.jvm.JvmName(
      name="TheRouterServiceProvideInjecter"
    )
3、两种反编译工具回放TheRouterServiceProvideInjecter.class字节码对应kotlin或者java源码。
// IntelliJ API Decompiler stub source generated from a class file
// Implementation of methods is not available
package a

@field:androidx.annotation.Keep @field:kotlin.jvm.JvmField internal var asm: kotlin.Boolean /* compiled code */

public fun addFlowTask(context: android.content.Context?, digraph: com.therouter.flow.Digraph): kotlin.Unit { /* compiled code */ }
public fun autowiredInject(obj: kotlin.Any?): kotlin.Unit { /* compiled code */ }
public fun initDefaultRouteMap(): kotlin.Unit { /* compiled code */ }
public fun trojan(): kotlin.Unit { /* compiled code */ }
package a;

import android.content.Context;
import androidx.annotation.Keep;
import com.therouter.flow.Digraph;
import kotlin.Metadata;
import kotlin.jvm.JvmField;
import kotlin.jvm.JvmName;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/* compiled from: TheRouterServiceProvideInjecter.kt */
@Metadata(mv = {1, 9, 0}, k = 2, xi = 48, d1 = {"��$\n��\n\u0002\u0010\u000b\n��\n\u0002\u0010\u0002\n��\n\u0002\u0018\u0002\n��\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010��\n\u0002\b\u0003\u001a\u0018\u0010\u0002\u001a\u00020\u00032\b\u0010\u0004\u001a\u0004\u0018\u00010\u00052\u0006\u0010\u0006\u001a\u00020\u0007\u001a\u0010\u0010\b\u001a\u00020\u00032\b\u0010\t\u001a\u0004\u0018\u00010\n\u001a\u0006\u0010\u000b\u001a\u00020\u0003\u001a\u0006\u0010\f\u001a\u00020\u0003"\u0012\u0010��\u001a\u00020\u00018��@��X\u0081\u000e¢\u0006\u0002\n��¨\u0006\r"}, d2 = {"asm", "", "addFlowTask", "", "context", "Landroid/content/Context;", "digraph", "Lcom/therouter/flow/Digraph;", "autowiredInject", "obj", "", "initDefaultRouteMap", "trojan", "router_debug"})

@JvmName(name = "TheRouterServiceProvideInjecter")
/* loaded from: TheRouterServiceProvideInjecter.class */
public final class TheRouterServiceProvideInjecter {
    @Keep
    @JvmField
    public static boolean asm;
    public static final void trojan() {
    }
    public static final void autowiredInject(@Nullable Object obj) {
    }
    public static final void addFlowTask(@Nullable Context context, @NotNull Digraph digraph) {
        Intrinsics.checkNotNullParameter(digraph, "digraph");
    }
    public static final void initDefaultRouteMap() {
    }
}
4、ASM插入代码后的TheRouterServiceProvideInjecter.class字节码反编译
package a;

import android.content.Context;
import com.therouter.TheRouter;
import com.therouter.app.navigator.NavigatorFragment2__TheRouter__Autowired;
import com.therouter.app.navigator.NavigatorFragmentActivity__TheRouter__Autowired;
import com.therouter.app.navigator.NavigatorFragment__TheRouter__Autowired;
import com.therouter.app.navigator.NavigatorTargetActivity2__TheRouter__Autowired;
import com.therouter.app.navigator.NavigatorTargetActivity__TheRouter__Autowired;
import com.therouter.app.navigator.ObjectTargetActivity__TheRouter__Autowired;
import com.therouter.app.test.Test2Activity__TheRouter__Autowired;
import com.therouter.demo.shell.MainActivity__TheRouter__Autowired;
import com.therouter.flow.Digraph;
import kotlin.Metadata;

@Metadata(d1 = {"\u0000$\n\u0000\n\u0002\u0010\u000b\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u001a\u0018\u0010\u0002\u001a\u00020\u00032\b\u0010\u0004\u001a\u0004\u0018\u00010\u00052\u0006\u0010\u0006\u001a\u00020\u0007\u001a\u0010\u0010\b\u001a\u00020\u00032\b\u0010\t\u001a\u0004\u0018\u00010\n\u001a\u0006\u0010\u000b\u001a\u00020\u0003\u001a\u0006\u0010\f\u001a\u00020\u0003"\u0012\u0010\u0000\u001a\u00020\u00018\u0000@\u0000X\u0081\u000e¢\u0006\u0002\n\u0000¨\u0006\r"}, d2 = {"asm", "", "addFlowTask", "", "context", "Landroid/content/Context;", "digraph", "Lcom/therouter/flow/Digraph;", "autowiredInject", "obj", "", "initDefaultRouteMap", "trojan", "router_debug"}, k = 2, mv = {1, 9, 0}, xi = 48)

/* loaded from: classes.dex */

public final class TheRouterServiceProvideInjecter {
    public static boolean asm = true;

    public static final void addFlowTask(Context context, Digraph digraph) {
        try {
            ServiceProvider__TheRouter__1173000296.addFlowTask(context, digraph);
        } catch (Throwable th) {
            th.printStackTrace();
        }
        try {
            ServiceProvider__TheRouter__1246883483.addFlowTask(context, digraph);
        } catch (Throwable th2) {
            th2.printStackTrace();
        }
        try {
            ServiceProvider__TheRouter__2113935708.addFlowTask(context, digraph);
        } catch (Throwable th3) {
            th3.printStackTrace();
        }
        try {
            ServiceProvider__TheRouter__794287541.addFlowTask(context, digraph);
        } catch (Throwable th4) {
            th4.printStackTrace();
        }
    }

    public static final void autowiredInject(Object obj) {
        try {
            NavigatorFragment2__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th) {
            th.printStackTrace();
        }
        try {
            NavigatorFragmentActivity__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th2) {
            th2.printStackTrace();
        }
        try {
            NavigatorFragment__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th3) {
            th3.printStackTrace();
        }
        try {
            NavigatorTargetActivity2__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th4) {
            th4.printStackTrace();
        }
        try {
            NavigatorTargetActivity__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th5) {
            th5.printStackTrace();
        }
        try {
            ObjectTargetActivity__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th6) {
            th6.printStackTrace();
        }
        try {
            Test2Activity__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th7) {
            th7.printStackTrace();
        }
        try {
            MainActivity__TheRouter__Autowired.autowiredInject(obj);
        } catch (Throwable th8) {
            th8.printStackTrace();
        }
    }

    public static final void initDefaultRouteMap() {
        try {
            RouterMap__TheRouter__582536616.addRoute();
        } catch (Throwable th) {
            th.printStackTrace();
        }
        try {
            RouterMap__TheRouter__881103503.addRoute();
        } catch (Throwable th2) {
            th2.printStackTrace();
        }
    }

    public static final void trojan() {
        try {
            TheRouter.getRouterInject().privateAddInterceptor(new ServiceProvider__TheRouter__1173000296());
        } catch (Throwable th) {
            th.printStackTrace();
        }
        try {
            TheRouter.getRouterInject().privateAddInterceptor(new ServiceProvider__TheRouter__1246883483());
        } catch (Throwable th2) {
            th2.printStackTrace();
        }
        try {
            TheRouter.getRouterInject().privateAddInterceptor(new ServiceProvider__TheRouter__2113935708());
        } catch (Throwable th3) {
            th3.printStackTrace();
        }
        try {
            TheRouter.getRouterInject().privateAddInterceptor(new ServiceProvider__TheRouter__794287541());
        } catch (Throwable th4) {
            th4.printStackTrace();
        }
    }
}
5、AMS API修改字节码
package com.therouter.plugin;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.AdviceAdapter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * AddCodeVisitor 类用于通过 ASM 修改字节码,注入 TheRouter 相关逻辑
 */
public class AddCodeVisitor extends ClassVisitor {

    private List<String> serviceProvideList; // 存储服务提供者类名列表
    private Map<String, String> serviceProvideMap; // 存储服务提供者类名及其版本信息
    private List<String> autowiredList; // 存储自动注入类名列表
    private List<String> routeList; // 存储路由类名列表
    private final boolean isIncremental; // 是否增量编译

    /**
     * 构造函数,初始化 ASM 访问器
     * @param cv ASM ClassVisitor 对象
     * @param serviceProvideMap 服务提供者类名及其版本信息
     * @param autowiredSet 自动注入类名集合
     * @param routeSet 路由类名集合
     * @param incremental 是否增量编译
     */
    public AddCodeVisitor(ClassVisitor cv, Map<String, String> serviceProvideMap, Set<String> autowiredSet, Set<String> routeSet, boolean incremental) {
        super(Opcodes.ASM7, cv);
        this.serviceProvideList = new ArrayList<>(serviceProvideMap.keySet());
        this.serviceProvideMap = serviceProvideMap;
        this.autowiredList = new ArrayList<>(autowiredSet);
        this.routeList = new ArrayList<>(routeSet);
        this.isIncremental = incremental;
        Collections.sort(this.serviceProvideList);
        Collections.sort(this.autowiredList);
        Collections.sort(this.routeList);
    }

    /**
     * 访问字段,修改特定字段的值
     * @param access 字段的访问修饰符
     * @param name 字段名
     * @param descriptor 字段描述符
     * @param signature 字段签名
     * @param value 字段初始值
     * @return FieldVisitor 对象
     */
    @Override
    public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
        if ("asm".equals(name) && "Z".equals(descriptor)) {
            return super.visitField(access, name, descriptor, signature, true);
        }
        return super.visitField(access, name, descriptor, signature, value);
    }

    /**
     * 访问方法,注入 TheRouter 相关逻辑
     * @param access 方法的访问修饰符
     * @param methodName 方法名
     * @param desc 方法描述符
     * @param signature 方法签名
     * @param exceptions 方法抛出的异常
     * @return MethodVisitor 对象
     */
    @Override
    public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, methodName, desc, signature, exceptions);
        mv = new AdviceAdapter(Opcodes.ASM7, mv, access, methodName, desc) {
            @Override
            protected void onMethodEnter() {
                super.onMethodEnter();

                if (!"<init>".equals(methodName)) {

                    if ("trojan".equals(methodName)) {
                        // 注入拦截器逻辑
                        // 遍历服务提供者类名列表
                        for (String serviceProviderClassName : serviceProvideList) {
                            // 检查服务提供者类名是否以 "a/" 开头,如果不是则添加 "a/" 前缀
                            if (!serviceProviderClassName.startsWith("a/")) {
                                serviceProviderClassName = "a/" + serviceProviderClassName;
                            }

                            //  后边asm想要插入的代码,
                            //  try {
                            //        // 调用 com.therouter.TheRouter 类的静态方法 getRouterInject 获取 RouterInject 实例
                            //        com.therouter.inject.RouterInject routerInject = com.therouter.TheRouter.getRouterInject();
                            //        // 创建一个指定服务提供者类的新对象
                            //        Class<?> serviceProviderClass = Class.forName(serviceProviderClassName.replace('/', '.'));
                            //        com.therouter.inject.Interceptor interceptor = (com.therouter.inject.Interceptor) serviceProviderClass.getDeclaredConstructor().newInstance();
                            //        // 调用 RouterInject 实例的 privateAddInterceptor 方法,将新创建的服务提供者对象作为拦截器添加
                            //        routerInject.privateAddInterceptor(interceptor);
                            //    } catch (Throwable e) {
                            //        // 打印异常堆栈信息
                            //        e.printStackTrace();
                            //    }

                            // 定义 Label 用于标记 try-catch 块的不同位置
                            // try 块的起始位置
                            Label tryStart = new Label();
                            // try 块的结束位置
                            Label tryEnd = new Label();
                            // catch 块的起始位置
                            Label labelCatch = new Label();
                            // try-catch 块结束后的位置
                            Label tryCatchBlockEnd = new Label();

                            // 使用 ASM 访问器定义一个 try-catch 块,捕获所有 Throwable 类型的异常
                            mv.visitTryCatchBlock(tryStart, tryEnd, labelCatch, "java/lang/Throwable");
                            // 标记 try 块的起始位置
                            mv.visitLabel(tryStart);

                            // 调用 com.therouter.TheRouter 类的静态方法 getRouterInject 获取 RouterInject 实例
                            mv.visitMethodInsn(INVOKESTATIC, "com/therouter/TheRouter", "getRouterInject", "()Lcom/therouter/inject/RouterInject;", false);
                            // 创建一个指定服务提供者类的新对象
                            mv.visitTypeInsn(NEW, serviceProviderClassName);
                            // 复制栈顶元素,用于后续的构造函数调用
                            mv.visitInsn(DUP);
                            // 调用指定服务提供者类的无参构造函数进行初始化
                            mv.visitMethodInsn(INVOKESPECIAL, serviceProviderClassName, "<init>", "()V", false);
                            // 调用 RouterInject 实例的 privateAddInterceptor 方法,将新创建的服务提供者对象作为拦截器添加
                            mv.visitMethodInsn(INVOKEVIRTUAL, "com/therouter/inject/RouterInject", "privateAddInterceptor", "(Lcom/therouter/inject/Interceptor;)V", false);

                            // 标记 try 块的结束位置
                            mv.visitLabel(tryEnd);
                            // 跳转到 try-catch 块结束后的位置
                            mv.visitJumpInsn(GOTO, tryCatchBlockEnd);

                            // 标记 catch 块的起始位置
                            mv.visitLabel(labelCatch);
                            // 将捕获到的异常对象存储到局部变量表索引为 1 的位置
                            mv.visitVarInsn(ASTORE, 1);
                            // 从局部变量表索引为 1 的位置加载异常对象到操作数栈
                            mv.visitVarInsn(ALOAD, 1);
                            // 调用异常对象的 printStackTrace 方法打印异常堆栈信息
                            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false);
                            // 标记 try-catch 块结束后的位置
                            mv.visitLabel(tryCatchBlockEnd);
                        }
                    }

                    if ("addFlowTask".equals(methodName)) {
                        // 注入任务依赖逻辑
                        for (String serviceProviderClassName : serviceProvideList) {
                            if (!serviceProviderClassName.startsWith("a/")) {
                                serviceProviderClassName = "a/" + serviceProviderClassName;
                            }
                            String aptVersion = serviceProvideMap.get(serviceProviderClassName);
                            if (aptVersion == null) {
                                aptVersion = serviceProvideMap.get(serviceProviderClassName.substring(2));
                            }

                            if (aptVersion != null && !aptVersion.equals("0.0.0")) {

                                //  后边asm想要插入的代码
                                //    try {
                                //        // 调用指定服务提供者类的静态方法 addFlowTask
                                //        // 传入 Android 上下文对象和有向无环图对象作为参数
                                //        Class<?> clazz = Class.forName(serviceProviderClassName.replace('/', '.'));
                                //        Method addFlowTaskMethod = clazz.getMethod("addFlowTask", Context.class, Digraph.class);
                                //        addFlowTaskMethod.invoke(null, context, digraph);
                                //    } catch (Throwable e) {
                                //        // 打印异常堆栈信息
                                //        e.printStackTrace();
                                //    }

                                // 定义 Label 用于标记 try-catch 块的不同位置
                                Label label0 = new Label();
                                Label label1 = new Label();
                                // catch 块的起始位置
                                Label label2 = new Label();
                                // catch 块的结束位置
                                Label tryCatchBlockEnd = new Label();

                                // 使用 ASM 访问器定义一个 try-catch 块,捕获所有 Throwable 类型的异常
                                // 起始位置为 label0,结束位置为 label1,异常处理位置为 label2
                                mv.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
                                // 标记 try 块的起始位置
                                mv.visitLabel(label0);

                                // 从局部变量表索引为 0 的位置加载对象引用到操作数栈
                                mv.visitVarInsn(ALOAD, 0);
                                // 从局部变量表索引为 1 的位置加载对象引用到操作数栈
                                mv.visitVarInsn(ALOAD, 1);
                                // 调用指定服务提供者类的静态方法 addFlowTask
                                // 传入 Android 上下文对象和有向无环图对象作为参数
                                mv.visitMethodInsn(INVOKESTATIC, serviceProviderClassName, "addFlowTask", "(Landroid/content/Context;Lcom/therouter/flow/Digraph;)V", false);

                                // 标记 try 块的结束位置
                                mv.visitLabel(label1);
                                // 跳转到 try-catch 块结束后的位置
                                mv.visitJumpInsn(GOTO, tryCatchBlockEnd);

                                // 标记 catch 块的起始位置
                                mv.visitLabel(label2);
                                // 将捕获到的异常对象存储到局部变量表索引为 2 的位置
                                mv.visitVarInsn(ASTORE, 2);
                                // 从局部变量表索引为 2 的位置加载异常对象到操作数栈
                                mv.visitVarInsn(ALOAD, 2);
                                // 调用异常对象的 printStackTrace 方法打印异常堆栈信息
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false);

                                // 标记 try-catch 块结束后的位置
                                mv.visitLabel(tryCatchBlockEnd);
                            }
                        }
                    }

                    if ("autowiredInject".equals(methodName)) {
                        // 注入自动注入逻辑
                        for (String autowiredClassName : autowiredList) {
                            //    下边是要插入的代码
                            //    try {
                            //        // 获取当前方法的第一个参数(即调用 autowiredInject 方法时传入的对象)
                            //        Object obj = getThisMethodFirstParameter();
                            //        // 加载自动注入类
                            //        Class<?> clazz = Class.forName(autowiredClassName);
                            //        // 获取自动注入类的静态方法 autowiredInject
                            //        java.lang.reflect.Method autowiredMethod = clazz.getMethod("autowiredInject", Object.class);
                            //        // 调用静态方法 autowiredInject 进行自动注入操作
                            //        autowiredMethod.invoke(null, obj);
                            //    } catch (Throwable e) {
                            //        // 打印异常堆栈信息
                            //        e.printStackTrace();
                            //    }

                            // 定义 Label 用于标记 try-catch 块的不同位置
                            // try 块的起始位置
                            Label tryStart = new Label();
                            // try 块的结束位置
                            Label tryEnd = new Label();
                            // catch 块的起始位置
                            Label labelCatch = new Label();
                            // try-catch 块结束后的位置
                            Label labelInvoke = new Label();

                            // 使用 ASM 访问器定义一个 try-catch 块,捕获所有 Throwable 类型的异常
                            mv.visitTryCatchBlock(tryStart, tryEnd, labelCatch, "java/lang/Throwable");
                            // 标记 try 块的起始位置
                            mv.visitLabel(tryStart);

                            // 从局部变量表索引为 0 的位置加载对象引用到操作数栈
                            mv.visitVarInsn(ALOAD, 0);
                            // 调用指定自动注入类的静态方法 autowiredInject
                            // 传入一个对象作为参数进行自动注入操作
                            mv.visitMethodInsn(INVOKESTATIC, autowiredClassName.replace('.', '/'), "autowiredInject", "(Ljava/lang/Object;)V", false);

                            mv.visitLabel(tryEnd);
                            mv.visitJumpInsn(GOTO, labelInvoke);

                            mv.visitLabel(labelCatch);
                            mv.visitVarInsn(ASTORE, 1);
                            mv.visitVarInsn(ALOAD, 1);
                            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false);

                            mv.visitLabel(labelInvoke);
                        }
                    }

                        // 注入路由初始化逻辑
                    if ("initDefaultRouteMap".equals(methodName)) {
                        for (String route : routeList) {
                            //    下边是要插入的代码
                            //    try {
                            //        // 处理类名,移除 .class 后缀并将 . 替换为 /
                            //        String className = route.replace(".class", "").replace('.', '/');
                            //        // 将类名转换为 Java 类名格式
                            //        String javaClassName = className.replace('/', '.');
                            //        // 加载路由类
                            //        Class<?> routeClass = Class.forName(javaClassName);
                            //        // 获取路由类的静态方法 addRoute
                            //        java.lang.reflect.Method addRouteMethod = routeClass.getMethod("addRoute");
                            //        // 调用静态方法 addRoute 进行路由初始化
                            //        addRouteMethod.invoke(null);
                            //    } catch (Throwable e) {
                            //        // 打印异常堆栈信息
                            //        e.printStackTrace();
                            //    }

                            Label tryStart = new Label();
                            Label tryEnd = new Label();
                            Label labelCatch = new Label();
                            Label tryCatchBlockEnd = new Label();

                            mv.visitTryCatchBlock(tryStart, tryEnd, labelCatch, "java/lang/Throwable");
                            mv.visitLabel(tryStart);

                            String className = route.replace(".class", "").replace('.', '/');
                            mv.visitMethodInsn(INVOKESTATIC, className, "addRoute", "()V", false);

                            mv.visitLabel(tryEnd);
                            mv.visitJumpInsn(GOTO, tryCatchBlockEnd);

                            mv.visitLabel(labelCatch);
                            mv.visitVarInsn(ASTORE, 1);
                            mv.visitVarInsn(ALOAD, 1);
                            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false);

                            mv.visitLabel(tryCatchBlockEnd);
                        }
                    }
                    if (!isIncremental) {
                        mv.visitInsn(RETURN);
                    }
                }
            }
        };
        return mv;
    }
}