gpt4 book ai didi

java - 使用 ASM 库覆盖 Java 字节码中的局部变量名称

转载 作者:行者123 更新时间:2023-11-30 08:44:35 24 4
gpt4 key购买 nike

我使用 Java 字节码的 ASM 库读取了一个类的方法及其内容。这是输出类中任意方法的局部变量名:

ClassReader reader = new ClassReader(new FileInputStream(new File("TheClass.class")));

final ClassNode classNode = new ClassNode();
reader.accept(classNode, 0);

for (final MethodNode mn : (List<MethodNode>)classNode.methods) {
for (LocalVariableNode n : (List<LocalVariableNode>)mn.localVariables) {
System.out.println(n.name);
}
}

这是编译后的源代码TheClass类文件:

public class TheClass {
public final String a;
public final String b;

public TheClass(String c, String d) {
this.b = d;
this.a = c;
}
}

所以逻辑上输出是this , c , d . 现在,我需要将这个已编译的类复制到一个新文件中,但要更改 <init>方法的参数(局部变量)为不同的名称( ef )。我该怎么做?我对 MethodVisitors 等几乎没有经验。

最佳答案

您需要编写一个适配器(ClassVisitor 的子类)并将其与 reader 链接起来。例如,

ClassReader reader = new ClassReader(new FileInputStream(new File("TheClass")));
ClassWriter writer = new ClassWriter(reader, 0);
TraceClassVisitor printer = new TraceClassVisitor(writer,
new PrintWriter(System.getProperty("java.io.tmpdir")
+ File.separator + name + ".log"));
ClassAdapter adapter = new ClassAdapter(printer);
reader.accept(adapter, 0);
byte[] b = writer.toByteArray();

有了它,您将获得byte[],您可以将其保存到文件中,或使用ClassLoader 加载到Class 中.

(TraceClassVisitor 只是另一个 ClassVisitor,我还链接它以在您的临时目录中获取人类可读的日志。)

适配器可能如下所示。您要覆盖的方法是 visitLocalVariable :

public class ClassAdapter extends ClassVisitor {
public ClassAdapter(ClassVisitor cv) {
super(Opcodes.ASM5, cv);
}

@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
return new MethodAdapter(mv);
}
}

public class MethodAdapter extends MethodVisitor {
public MethodAdapter(MethodVisitor mv) {
super(Opcodes.ASM5, mv);
}

@Override
public void visitLocalVariable(String name, String desc, String signature,
Label start, Label end, int index) {
// Put your rename logic here
if (name.equals("c"))
name = "e";
else if (name.equals("d"))
name = "f";
super.visitLocalVariable(name, desc, signature, start, end, index);
}
}

关于java - 使用 ASM 库覆盖 Java 字节码中的局部变量名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33716596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com