我想将代理附加到进程并修改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
答案 0 :(得分:1)
在ToStringTransformer
中,您具有以下代码:
CtMethod ctMethod = ctClass.getDeclaredMethod("toString");
ctMethod.setBody("return true;");
ctClass.writeFile();
toString
返回一个String
,但是在这里您试图使它通过boolean
返回一个return true
。当您尝试加载已修改的类时,这将引发VerifyError
,因为堆栈({true
)上的返回值将与{{ 1}}方法(toString
)。