当前位置: 首页 > 面试题库 >

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

齐航
2023-03-14
问题内容

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

这是身份转换器,我希望得到的修改数组的大小与字节1相同,但要短2倍!(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();

加载失败没有什么奇妙的。我怀疑标头被截断了,但是两个数组中的第一个字节都相同。

-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类文件幻数匹配的字节0xcafebabe

这里的问题是,new ClassWriter(reader, 0)您无法做到自己想像的那样。请参阅API文档:

classReader-用于读取原始类的ClassReader。它将用于从原始类复制整个常量池,并在适用的情况下复制原始字节码的其他片段。

我们实际上仍然需要作者通过来 访问
读者ClassReader.accept,如下所示:

reader.accept(writer, 0);

附带说明一下,您不需要IOUtils.toByteArary像那样ClassReader的构造函数InputStream



 类似资料:
  • 问题内容: 类 BasicLabelUI 中 的javax /秋千/ PLAF /基本 是通过影响已确认的bug。在我的应用程序中,我 需要 固定版本(适用于v9)提供的功能。由于法律和技术方面的原因,我仍然受受影响的JDK版本的约束。 我的方法是在项目内部创建一个包含固定版本的包 javax / swing / plaf / basic 。 与已安装的JDK中的缺陷类相比,我该如何强迫我的项目偏

  • 拾取java_tool_options:'-dfile.encoding=utf8' > ////由Procyon v0.5.30反编译//

  • 我正在尝试使用visual studio代码for Java。 Java.lang.UnsupportedClassVersionError:HelloWorld是由最新版本的Java运行时(类文件版本53.0)编译的,这个版本的Java运行时只识别Java.lang.ClassLoader.DefineClass1(本机方法)中高达52.0的类文件版本......……。在sun.launcher

  • 假设您知道您的软件只会在符号溢出行为定义良好的两台互补机器上运行。签名溢出在C和C中仍然是未定义的行为,编译器可以用“ret”替换整个程序,启动核战争,格式化驱动器,或者让恶魔从你的鼻子里飞出来。 假设您在内联 asm 中进行了签名溢出,您的程序是否仍会调用 UB? 如果是,那么单独编译和链接的汇编程序呢?

  • 我想在我的自定义PHP文件中显示wpdatatables(插件),所以我想使用“do_shortcode()”函数,但没有任何效果,它只是显示白色屏幕。 我的php文件代码:

  • 错误:将字节码转换为dex时出错:原因:com.android.dex。DexException:多个dex文件定义Landroid/arch/lifecycle/LiveData$LifecycleBoundObserver; 我的 gradle 文件 **这就是错误,我明白了**