You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8+ASM 5.0.3修改JVM已加载类字节码的实现疑问

运行时修改已加载类的字节码实现方案

针对你的需求(JVM加载类后修改字节码、Java 8+ASM 5.0.3、无JVM启动参数),可以通过Java Attach API + Instrumentation类重定义实现,核心思路是动态挂载Agent,再用ASM修改目标方法的字节码。

实现步骤与代码

1. 编写ASM字节码修改逻辑(Agent类)

这个类负责接收Instrumentation实例,读取目标类字节码并修改方法体:

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

import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;

public class BytecodeInjectAgent {
    public static void agentmain(String agentArgs, Instrumentation inst) throws Exception {
        // 获取目标类
        Class<?> targetClass = ExampleObject.class;
        // 读取原有字节码
        ClassReader cr = new ClassReader(targetClass.getName());
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
        
        // 自定义ClassVisitor拦截目标方法
        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
            @Override
            public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
                MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
                // 仅处理exampleMethod方法
                if ("exampleMethod".equals(name) && "(Ljava/lang/Object;)V".equals(descriptor)) {
                    return new MethodVisitor(Opcodes.ASM5, mv) {
                        @Override
                        public void visitCode() {
                            // 在方法开头插入调用methodToInject的指令
                            // 1. 加载方法参数o到操作数栈
                            mv.visitVarInsn(Opcodes.ALOAD, 1);
                            // 2. 调用Example类的静态方法methodToInject
                            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "Example", "methodToInject", "(Ljava/lang/Object;)V", false);
                            // 3. 执行原有方法逻辑
                            super.visitCode();
                        }
                    };
                }
                return mv;
            }
        };
        
        cr.accept(cv, ClassReader.SKIP_FRAMES);
        // 生成修改后的字节码并触发类重定义
        byte[] modifiedBytes = cw.toByteArray();
        inst.redefineClasses(new ClassDefinition(targetClass, modifiedBytes));
    }
}

2. 修改主类的injectAtHead方法

通过Attach API动态挂载Agent,无需启动参数:

import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import java.lang.management.ManagementFactory;
import java.io.IOException;

// 位于某库中
class ExampleObject {
    public void exampleMethod(Object o) {
        System.out.println("Body " + o);
    }
}

public class Example {
    // 来自同一库
    public static final ExampleObject exampleObject = new ExampleObject();

    public static void main(String[] args) {
        exampleObject.exampleMethod(1);
        injectAtHead();
        exampleObject.exampleMethod(2);
    }

    public static void injectAtHead() {
        // 获取当前进程PID
        String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        try {
            // 附加到当前进程并加载Agent
            VirtualMachine vm = VirtualMachine.attach(pid);
            // 替换为你的Agent Jar实际路径
            vm.loadAgent("bytecode-inject-agent.jar");
            vm.detach();
        } catch (AttachNotSupportedException | IOException | Exception e) {
            e.printStackTrace();
        }
    }

    public static void methodToInject(Object o) {
        System.out.println("Head " + o);
    }
}

3. 打包Agent Jar(关键配置)

创建MANIFEST.MF文件,指定Agent入口和权限:

Manifest-Version: 1.0
Agent-Class: BytecodeInjectAgent
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Class-Path: asm-5.0.3.jar

打包时将ASM 5.0.3的Jar、所有编译后的class文件一起打包,确保MANIFEST.MF被正确包含。

注意事项

  • 依赖:必须引入ASM 5.0.3 Jar,以及JDK的tools.jar(Java 8中Attach API位于此Jar,需添加到类路径)。
  • 权限:运行程序时需要足够的系统权限(比如Linux下需允许进程附加,Windows下可能需要管理员权限)。
  • JVM限制:类重定义不能修改类的继承结构、不能新增/删除字段或方法(仅修改方法体是合法的)。

内容的提问来源于stack exchange,提问作者crazycat256

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 19:24:52