java - 读取.class文件

标签 java c++ .class-file

我正在尝试学习如何使用 C++ 读取 Java 类文件。谁能帮我弄清楚为什么 AccessFlag 打印 0?它可以打印的最低值是 0x00001。所以我认为我读错了常量台球表,但我不确定它有什么问题。有任何想法吗?我在关注:http://www.murrayc.com/learning/java/java_classfileformat.shtml

到目前为止我得到了:

#include <iostream>
#include <fstream>
#include <vector>

template <typename T>
T ReadPointer(char*& Pointer)
{
    T Result = *(reinterpret_cast<T*>(Pointer));
    Pointer += sizeof(T);
    return Result;
}

struct ConstantPool
{
    int type;
    std::string name;
    ConstantPool*  arg1;
    ConstantPool*  arg2;
    short index1, index2;
    std::string  strValue;
    int   intValue;
    std::int64_t  longValue;
    float floatValue;
    double  doubleValue;

    ConstantPool() {}
    ConstantPool(char* &Pointer) {this->Read(Pointer);}
    void Read(char* &Pointer);
};

void ConstantPool::Read(char* &Pointer)
{
    switch(type = static_cast<int>(ReadPointer<std::uint8_t>(Pointer)))
    {
        case 1:
        {
            name = "Ascii";
            int Length = ReadPointer<short>(Pointer);
            while (Length > 0)
            {
                char C = ReadPointer<char>(Pointer);
                strValue += C;
                Length--;
            }
        }
        break;

        case 2:
        {
            name = "Unicode";
            int Length = ReadPointer<short>(Pointer);
            while (Length > 0)
            {
                char C = ReadPointer<char>(Pointer);
                strValue += C;
                Length--;
            }
        }
        break;

        case 3:
            name = "Int";
            intValue = ReadPointer<double>(Pointer);
            break;

        case 4:
            name = "Float";
            floatValue = ReadPointer<float>(Pointer);
            break;

        case 5:
            name = "Long";
            longValue = ReadPointer<long>(Pointer);
            break;

        case 6:
            name = "Double";
            doubleValue = ReadPointer<double>(Pointer);
            break;

        case 7:
            name = "Class";
            index1 = ReadPointer<short>(Pointer);
            index2 = -1;
            break;

        case 8:
            name = "String";
            index1 = ReadPointer<short>(Pointer);
            index2 = -1;
            break;

        case 9:
            name = "Field Reference";
            index1 = ReadPointer<short>(Pointer);
            index2 = ReadPointer<short>(Pointer);
            break;

        case 10:
            name = "Method Reference";
            index1 = ReadPointer<short>(Pointer);
            index2 = ReadPointer<short>(Pointer);
            break;

        case 11:
            name = "Interface Reference";
            index1 = ReadPointer<short>(Pointer);
            index2 = ReadPointer<short>(Pointer);
            break;

        case 12:
            name = "Name And Type";
            index1 = ReadPointer<short>(Pointer);
            index2 = ReadPointer<short>(Pointer);
            break;
    }
}

typedef struct
{
    int MagicNumber;
    short MinorVersion;
    short MajorVersion;
    short ConstantPoolCount;

} ClassFile;

int main()
{
    std::fstream File("Animal.class", std::ios::in | std::ios::binary);
    if (File.is_open())
    {
        File.seekg(0, std::ios::end);
        std::vector<std::uint8_t> Data(File.tellg());
        char* Ptr = reinterpret_cast<char*>(&Data[0]);
        File.seekg(0, std::ios::beg);
        File.read(Ptr, Data.size());

        /**Check Magic Number.**/
        ClassFile BaseInfo = ReadPointer<ClassFile>(Ptr);
        if (BaseInfo.MagicNumber == 0xBEBAFECA)
        {
            std::cout << "Magic Number:    " << BaseInfo.MagicNumber << "\n";
            std::cout << "Minor Number:    " << BaseInfo.MinorVersion << "\n";
            std::cout << "Major Number:    " << BaseInfo.MajorVersion << "\n";
            std::cout << "Const Pool Size: " << BaseInfo.ConstantPoolCount << "\n";
            std::vector<ConstantPool> ConstPool;

            for (int I = 0; I < BaseInfo.ConstantPoolCount - 1; ++I)
            {
                ConstPool.push_back(ConstantPool(Ptr));
                if (ConstPool.back().type == 5 || ConstPool.back().type == 6)
                    ++I;
            }

            std::cout << "Access Flags:   " << ReadPointer<short>(Ptr);
        }

        File.close();
    }
}

最佳答案

一个错误是

intValue = ReadPointer<double>(Pointer);

您正在读取一个 double 而不是一个 int,这将抛开其他一切。

当然,您的代码还有很多其他问题。例如,您完全忽略了对齐和结构填充问题。

关于java - 读取.class文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17984454/

相关文章:

c++ - Rust 中不止一个运算符重载

没有等号的 C++ Regex Alpha

java - 类文件到Java文件的转换

android - 将 Java 类作为函数参数发送

java - 在编译时插入字符串

java 与 postgresql 语句错误

c++ - 使用stringstream.fail()检查输入是int还是string

java - 类文件常量池(javap)中的方法签名和描述符

java CallableStatement 打印过程中的所有参数

java - 如何在表格单元格编辑器中给 JTable 单元格选择背景和前景色