Skip to content

Problem in parsing 2 files #190

@az55555

Description

@az55555

Thanks for the great project! I'm trying to use it for reading versions from executables.
I've built it with Qt Creator, gcc, qbs (see my .qbs and .cpp files in the archive): pe-parse.zip
Most EXE and DLL files I've tried were parsed fine but two of them failed:

  • System.Text.Json.dll - getDebugDir fails. Since this file has an Authenticode signature of .NET project, it's unlikely that the file is currupt.
  • ConfKarat.exe - incorrect version resource is passed to IterRsrc callback. Windows explorer file properties box shows the version. I can also see the version in a hex editor. But res.buf->buf in my code doesn't point to anything containing VS_VERSION_INFO and 0xfeef04bd signature.

Here is my code:

struct MY_VS_FIXEDFILEINFO
{
    quint32 dwSignature;
    quint32 dwStrucVersion;
    quint32 dwFileVersionMS;
    quint32 dwFileVersionLS;
    quint32 dwProductVersionMS;
    quint32 dwProductVersionLS;
    quint32 dwFileFlagsMask;
    quint32 dwFileFlags;
    quint32 dwFileOS;
    quint32 dwFileType;
    quint32 dwFileSubtype;
    quint32 dwFileDateMS;
    quint32 dwFileDateLS;
};

int extractVersionFromResourceCallback(void* ptr, const peparse::resource& res)
{
    // Skip all resource types execpt RT_VERSION
    if(res.type != 16) return 0;

    // Find VS_FIXEDFILEINFO in the buffer
    auto structSize = sizeof(MY_VS_FIXEDFILEINFO);
    for(size_t offset = 0; offset + structSize <= res.size; offset += 4)
    {
        auto verInfo = (const MY_VS_FIXEDFILEINFO*)(res.buf->buf + offset);
        if (verInfo->dwSignature == 0xfeef04bd)
        {
            QString& result = *(QString*)ptr;
            result = QStringLiteral("%1.%2.%3.%4")
                .arg(( verInfo->dwFileVersionMS >> 16 ) & 0xffff)
                .arg(( verInfo->dwFileVersionMS >>  0 ) & 0xffff)
                .arg(( verInfo->dwFileVersionLS >> 16 ) & 0xffff)
                .arg(( verInfo->dwFileVersionLS >>  0 ) & 0xffff);
            return 1;
        }
    }

    // Maybe there's another version resource we'll understand
    return 0;
}

...

    // Have to use mutex because pe-parse library uses globals
    static QMutex peparseMutex;
    QMutexLocker locker(&peparseMutex);

    // Try to parse PE
    auto peptr = peparse::ParsePEFromPointer((std::uint8_t*)m_data.data(), m_data.size());
    if (peptr == nullptr)
    {
        qWarning() << "Failed to parse PE. Code:" << peparse::GetPEErr() << endl
                   << "Error:" << QString::fromStdString(peparse::GetPEErrString()) << endl
                   << "Location:" << QString::fromStdString(peparse::GetPEErrLoc());
        return QString();
    }

    // Make sure we cleanup properly
    try
    {
        // Iterate resources
        QString result;
        peparse::IterRsrc(peptr, extractVersionFromResourceCallback, &result);
        DestructParsedPE(peptr);
        return result;
    }
    catch (...)
    {
        DestructParsedPE(peptr);
        throw;
    }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions