使用instrumentation.addTransformer(transformer,true)时为“ java.lang.VerifyError”;

时间:2019-07-29 08:12:16

标签: java

我想将代理附加到进程并修改vm中的类代码。当我添加转换器并调用retransformClasses时,它将引发photo_1 = models.ImageField(upload_to=image_path, blank=True) photo_2 = models.ImageField(upload_to=image_path, blank=True) photo_3 = models.ImageField(upload_to=image_path, blank=True) 。代理程序正在处理中,请在main中调用attach

主要:

java.lang.VerifyError

代理商:

public static void main(String[] args) throws Exception {
    Agent.attach();
    Order order = new Order();
    Agent.modify("com.tostring.agent.Order");
    order.toString();
}

ToStringTransformer

public static void attach() throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException, URISyntaxException {
    int processID = getProcessID();
    VirtualMachine vm = VirtualMachine.attach(String.valueOf(processID));
    String filePath = Agent.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
    File file = new File(filePath);
    vm.loadAgent(file.getPath());
}

public static int getProcessID() {
    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    return Integer.valueOf(runtimeMXBean.getName().split("@")[0]);
}

public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Throwable {
    Agent.instrumentation = instrumentation;
}

public static void premain(String agentArgs, Instrumentation instrumentation) throws Throwable {
    Agent.instrumentation = instrumentation;
}

public static void modify(String className) {
    Arrays.stream(instrumentation.getAllLoadedClasses()).forEach((aClass) -> {
        if (className.equals(aClass.getName())) {
            ClassFileTransformer transformer = new ToStringTransformer();
            instrumentation.addTransformer(transformer, true);

            try {
                instrumentation.retransformClasses(new Class[]{aClass});
                instrumentation.removeTransformer(transformer);
            } catch (UnmodifiableClassException var4) {
                var4.printStackTrace();
            }
        }

    });
}

日志显示它不是转换器public class ToStringTransformer implements ClassFileTransformer { public ToStringTransformer() { } public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { String compareClass = className.replace('/', '.'); System.out.println("transformer..." + compareClass); if (loader == null) { return classfileBuffer; } else { try { ClassPool classPool = ClassPool.getDefault(); classPool.appendClassPath(Agent.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); CtClass ctClass = classPool.get(compareClass); CtMethod ctMethod = ctClass.getDeclaredMethod("toString"); ctMethod.setBody("return true;"); ctClass.writeFile(); return ctClass.toBytecode(); } catch (Exception var10) { var10.printStackTrace(); return new byte[0]; } } } } ,而是其他类,例如com.tostring.agent.Order

java.lang.VerifyError

1 个答案:

答案 0 :(得分:1)

ToStringTransformer中,您具有以下代码:

CtMethod ctMethod = ctClass.getDeclaredMethod("toString");
ctMethod.setBody("return true;");
ctClass.writeFile();

toString返回一个String,但是在这里您试图使它通过boolean返回一个return true。当您尝试加载已修改的类时,这将引发VerifyError,因为堆栈({true上的返回值将与{{ 1}}方法toString