gpt4 book ai didi

java - 我正在尝试学习用于字节码检测的 java asm 框架,但找不到足够的文档或教程

转载 作者:行者123 更新时间:2023-11-29 07:42:47 25 4
gpt4 key购买 nike

我正在尝试学习用于字节码检测的 java asm 框架,但找不到足够的文档或教程。

我研究过 ClassReaderClassWriterClassVisitor 以及一些更相似的 API,但不太清楚如何实现这些 API 以及如何实现它们编写相应的适配器。

假设我有一个 HelloWorld java 类。

public class HelloWorld {

public static void main(String[] args) {
//some code.....

}

}

现在我想插入一个变量“int i =10;”在字节码中。请告诉我应该编写什么适配器/程序。

提前致谢!

最佳答案

以下是一种向类添加附加字段的方法,例如“int i = 10;”。假设您正在使用 javaagent 执行检测:1)使用下面的作为java代理的premain类

import java.lang.instrument.Instrumentation;

public class SimpleAgent {

public static void premain(String agentArgs, Instrumentation inst) {

ClassTransformer transformer = new ClassTransformer();
inst.addTransformer(transformer);
}
}

2) addTransformer调用ClassTransformer类的transform方法,定义如下

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;

public class ClassTransformer implements ClassFileTransformer{
public byte[] transform(ClassLoader loader,
String className,
Class classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] b)
throws IllegalClassFormatException {
try
{
ClassReader cr=new ClassReader(b);
ClassWriter cw = new ClassWriter(cr,ClassWriter.COMPUTE_MAXS);
AddField cp = new AddField(cw);
cr.accept(cp,0);
return cw.toByteArray();
}
catch(Exception e)
{
System.out.println(e);
}
return b;
}
}

3) 最后如下的AddField是ClassVisitor,负责给类增加一个新的字段

import static org.objectweb.asm.Opcodes.ASM4;
import org.objectweb.asm.ClassVisitor;


class AddField extends ClassVisitor{

static String className;
static String methName, descrip;
public AddField(ClassVisitor cv) {
super(ASM4, cv);
}

@Override
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces) {
className = name;
cv.visit(version, access, name, signature, superName, interfaces);
}
public void visitEnd() {
cv.visitField(0, "i", "I", null , new Integer(10));
cv.visitEnd();
}
}

4. ** 新编辑 ** 用于将变量添加到方法中。该变量必须存储到一个临时变量中,以后可以使用。以下适配器可用于此目的(查看 onMethodEnter):

import static org.objectweb.asm.Opcodes.ASM4;
import static org.objectweb.asm.Opcodes.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.AdviceAdapter;

public class MethodAdapter extends ClassVisitor {


public MethodAdapter(ClassVisitor cv) {
super(ASM4, cv);
}

@Override
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces) {
cv.visit(version, access, name, signature, superName, interfaces);
}


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


public class AddVariableAdapter extends AdviceAdapter{
public AddCallAdapter(int access, String name, String desc,
MethodVisitor mv) {
super(ASM4, mv, access, name, desc);
}

protected void onMethodEnter() {
mv.visitIntInsn(BIPUSH, 10); // pushes the number 10 on to the stack
mv.visitVarInsn(ISTORE, 1); // pops the top of the stack into a local variable indexed by 1
/* code to print the local variable
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitVarInsn(ILOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V");*/
}
}
}

关于java - 我正在尝试学习用于字节码检测的 java asm 框架,但找不到足够的文档或教程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28580323/

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