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

如何使用ASM修改静态变量值?Java Agent新手实操求助

Hey there! I totally get how confusing Java Agents can be when you're starting out—most docs skip over the basic, hands-on details that newbies need. Let's walk through this step by step to modify that x value in your Multiplier class.

1. Quick Primer on Java Agents for Newbies

Java Agents let you modify bytecode before or during your main program's execution. For beginners, the easiest entry point is the premain method: this runs before your main class's main method, giving you a chance to tweak the bytecode.

2. Build Your Agent (With Bytecode Tweaks)

We'll use ASM (a lightweight, widely-used bytecode manipulation library) to modify the x variable—manual bytecode editing is way too error-prone for starters.

Step 2.1: Create the Agent Entry Class

First, make a class that acts as the agent's starting point:

import java.lang.instrument.Instrumentation;

public class ModifyXAgent {
    // This is the mandatory entry point for a premain agent
    public static void premain(String agentArgs, Instrumentation inst) {
        // Register a transformer to modify the Multiplier class's bytecode
        inst.addTransformer(new MultiplierClassTransformer());
        System.out.println("Agent loaded successfully!"); // Debug check
    }
}

Step 2.2: Write the Bytecode Transformer

This class will scan the Multiplier class's bytecode and change the value assigned to x:

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.ClassFileTransformer;
import java.security.ProtectionDomain;

public class MultiplierClassTransformer implements ClassFileTransformer {
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                            ProtectionDomain protectionDomain, byte[] classfileBuffer) {
        // Target only the Multiplier class (className uses / instead of .)
        if ("Multiplier".equals(className.replace("/", "."))) {
            ClassReader cr = new ClassReader(classfileBuffer);
            ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
            
            // Custom ClassVisitor to inspect and modify methods
            ClassVisitor cv = new ClassVisitor(Opcodes.ASM9, cw) {
                @Override
                public MethodVisitor visitMethod(int access, String name, String descriptor,
                                                String signature, String[] exceptions) {
                    MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
                    
                    // Target only the main method (match name and method descriptor)
                    if ("main".equals(name) && "([Ljava/lang/String;)V".equals(descriptor)) {
                        return new MethodVisitor(Opcodes.ASM9, mv) {
                            @Override
                            public void visitIntInsn(int opcode, int operand) {
                                // Find the instruction that pushes 10 (x's initial value)
                                // In bytecode, int x =10; translates to BIPUSH 10
                                if (opcode == Opcodes.BIPUSH && operand == 10) {
                                    // Change 10 to your desired value (e.g., 20)
                                    super.visitIntInsn(opcode, 20);
                                    System.out.println("Modified x's value from 10 to 20!");
                                } else {
                                    super.visitIntInsn(opcode, operand);
                                }
                            }
                        };
                    }
                    return mv;
                }
            };
            cr.accept(cv, ClassReader.EXPAND_FRAMES);
            return cw.toByteArray();
        }
        // Leave other classes untouched
        return classfileBuffer;
    }
}

Step 2.3: Get ASM Dependencies

Since we're using ASM, download these two JARs and add them to your Eclipse project:

  • asm.jar (core ASM library)
  • asm-commons.jar (optional but simplifies some operations)

3. Package the Agent into a JAR

Eclipse needs a custom manifest to recognize this as a Java Agent:

  1. Create a MANIFEST.MF file in your project's root with this content:
Premain-Class: ModifyXAgent
Can-Redefine-Classes: true
  1. Export your agent project as a JAR, making sure to include the manifest and ASM classes (or keep ASM JARs separate and add them to the classpath later).

4. Run Your Main Program with the Agent

Open a command prompt and run this command (replace paths with your actual JAR locations):

java -javaagent:path/to/ModifyXAgent.jar -jar path/to/Multiplier.jar

You should see output like:

Agent loaded successfully!
Modified x's value from 10 to 20!
Multiply of x*y = 500

Key Tips for Newbies

  • Check Bytecode with javap: Run javap -c Multiplier.class in your terminal to see the raw bytecode of your main class. This helps you match the exact instructions you need to modify (like BIPUSH 10 for int x=10).
  • Debug First: Add print statements in your agent to confirm it's loading correctly before troubleshooting bytecode issues.
  • ASM Version Match: Use the latest stable ASM version (like ASM9) to avoid compatibility bugs with newer Java versions.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:26:29