问题 ClassFormatError:类XY中的未知常量标记


我有一段代码,我尝试在运行时加载一个类。代码不是全部自写的,所以我在理解编译后总是出现的错误时遇到了一些问题。

这里的代码:

private Class findClass(String s)
        throws ClassNotFoundException
    {
        URL url = getResource("AP.class");
        if(url == null)
        {
            throw new ClassNotFoundException(s);
        }
        inputstream = null;
        Class classToRead;
        try
        {
            inputstream = url.openStream();
            byte abyte0[] = readClass(inputstream);
            classToRead= defineClass(s, abyte0, 0, abyte0.length);
        }
        catch(IOException ioexception)
        {
            throw new ClassNotFoundException(s);
        }
        if(inputstream != null)
        {
            try
            {
                inputstream.close();
            }
            catch(Exception exception1) { }
        }
        return classToRead;
    }

该错误出现在defineClass方法中。

错误堆栈跟踪:

Exception in thread "main" java.lang.ClassFormatError: Unknown constant tag 63 in class file AP
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at c.findClass(c.java:100)
    at c.loadClass(c.java:56)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at c.a(c.java:20)
    at mainOpenClass.main(lol.java:13)

我现在的问题是: 代码可能有问题吗? AP.class可能已损坏吗? 这个错误究竟意味着什么?

我希望任何人都可以帮助我解决我的问题,因为在这种情况下搜索互联网并没有真正帮助我。


10746
2017-09-08 19:37


起源

你是怎么扔的 ClassNotFoundException 当一个 IOException 被抓了? - Phani Rahul
我认为错误不是IOException,因此稍后会被捕获。 - Mister004


答案:


你自己编写的代码很好。问题是 AP.class 是一个损坏的类文件 - 因此 ClassFormatError

错误本身意味着它无法正确解码 恒定的池,类文件结构的一部分,非常像符号表。看到 Java虚拟机规范的§4.4

Java虚拟机指令不依赖于类,接口,类实例或数组的运行时布局。相反,指令指的是符号信息 constant_pool 表。

所有 constant_pool 表条目具有以下一般格式:

cp_info {
    u1 tag;
    u1 info[];
}

中的每个项目 constant_pool 表必须以1字节标记开头,表示其类型 cp_info 条目。 info数组的内容随tag的值而变化。有效标记及其值列在 表4.3。每个标记字节后面必须跟有两个或多个字节,提供有关特定常量的信息。附加信息的格式随标签值而变化。

因此,错误本身告诉您该类具有带有无效标记的常量池表条目,即 63。事实上,使用上面提到的表4.3进行验证 这与任何记录的类型都不对应 cp_info 条目

尝试重新下载 AP.class。鉴于名称晦涩(AP, 以及 c 从堆栈跟踪),我将假设您正在尝试使用一些混淆代码。不仅要验证您尝试处理的代码不会受到某种加密的进一步保护,而且还要验证您所做的任何预处理(例如反混淆)都不会破坏数据。


10
2017-09-08 20:02



我假设“你试图处理的代码”是指AP.class中的代码。有了这个假设,我不知道如何检查任何加密。有没有一种简单的方法来检查? PS:谢谢你的回答! - Mister004
找到通常使用的代码 AP.class 并在定义类之前查看它是否进行任何预处理。它可能正在加密它。 - oldrinb
多数民众赞成的问题,我没有这样的代码。这是该类首次出现在代码中。一些背景信息,以便我的问题听起来不是愚蠢的。代码是您获得Java程序的挑战的一部分,必须对其进行反编译并找到密码。我的假设是密码在这个类中,我无法阅读。你能想象如何用这种知识阅读课程吗? - Mister004
@ Mister004你能告诉我这个裂缝吗? - oldrinb
如果你能告诉我怎么送你拉链^^ - Mister004


您的问题的答案:

  1. 没有

  2. 来自Java Doc Java虚拟机尝试时抛出 读取类文件并确定文件格式错误或 否则无法解释为类文件。


0
2017-09-08 19:47



好,谢谢。这意味着没有AP.class的源代码,只有文件本身,我不可能阅读该类?或者有没有办法“恢复”课程? - Mister004
你可以尝试使用jad反编译器...... - Sergii Zagriichuk
试了一下。不幸的是,如果我直接反编译它也会出错。 - Mister004
它发生是因为类文件已损坏 - Sergii Zagriichuk