gpt4 book ai didi

java - 如何使用ASM进行字节码转换后定义类(类文件版本0.0)

转载 作者:行者123 更新时间:2023-11-30 02:50:15 25 4
gpt4 key购买 nike

我无法加载使用 ASM 库修改字节码后的类。

这里是恒等更改器(mutator),我希望得到与字节一大小相同的修改后的数组,但它短了两倍! (439 比 278)

    String path = SimpleClass.class.getName().replace(".", "/") + ".class";
ClassLoader classLoader = SimpleClass.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream(path);

byte[] bytes = IOUtils.toByteArray(is);

ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, 0);
byte[] modified = writer.toByteArray();

加载失败没什么奇怪的。我怀疑 header 被截断,但第一个字节是相同的两个数组。

-54、-2、-70

static class ByteClassLoader extends ClassLoader {
public Class define(String name, byte[] body) {
return defineClass(name, body, 0, body.length);
}
}

ByteClassLoader myLoader = new ByteClassLoader();
Class myClass = myLoader.define("Ooo", modified);

因错误而失败:

java.lang.UnsupportedClassVersionError: Ooo has been compiled by a more  recent version of the Java Runtime (class file version 0.0), this version of the Java Runtime only recognizes class file versions up to 52.0

at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
at PrintTest$ByteClassLoader.define(PrintTest.java:24)
at PrintTest.x(PrintTest.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:253)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)

最佳答案

这些字节对应于 0xcafeba,它与 Java 类文件魔数(Magic Number) 0xcafebabe 相匹配。

这里的问题是 new ClassWriter(reader, 0) 并没有做你可能认为它会做的事情;请参阅API documentation :

classReader - the ClassReader used to read the original class. It will be used to copy the entire constant pool from the original class and also to copy other fragments of original bytecode where applicable.

我们仍然需要让作者通过 ClassReader.accept 访问读者。 ,如下:

reader.accept(writer, 0);
<小时/>

顺便说一句,您不需要 IOUtils.toByteArray 因为 ClassReader 有一个 constructor taking InputStream .

关于java - 如何使用ASM进行字节码转换后定义类(类文件版本0.0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38917284/

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