正在读取.class文件

Reading .class file

本文关键字:文件 class 读取      更新时间:2023-10-16

我正在学习如何使用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,这会把其他的东西都扔掉。

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