// Detect It Easy: detection rule file
// Author: horsicq <horsicq@gmail.com>

// This file has a lot of results
// Microsoft linker
// Microsoft Visual C/C++
// Visual Basic
// MASM
// MFC

// Rewritten by DosX: 2 jul 2025

function detect() {
    var linkerName = String(),
        linkerVersion = String(),
        linkerOptions = String(),
        cppCompilerName = String(),
        cppCompilerVersion = String(),
        cppCompilerOptions = String(),
        masmCompilerName = String(),
        masmCompilerVersion = String(),
        masmCompilerOptions = String(),
        vbCompilerName = String(),
        vbCompilerVersion = String(),
        vbCompilerOptions = String(),
        dotNetLibraryName = String(),
        dotNetLibraryVersion = String(),
        dotNetLibraryOptions = String(),
        mfcLibraryName = String(),
        mfcLibraryVersion = String(),
        mfcLibraryOptions = String(),
        toolName = String(),
        toolVersion = String(),
        toolOptions = String();




    //
    // ==================================================
    //     Advanced detection of .NET applications
    // ==================================================
    //        Author: DosX
    //        E-Mail: collab@kay-software.ru
    //        GitHub: https://github.com/DosX-dev
    //        Telegram: @DosX_dev
    // ==================================================
    //

    function findNetCoreConfigOffset() {
        return PE.findString(PE.section[0].FileOffset, PE.getSize(), ".NETCoreApp,Version=v");
    }

    function findNetFrameworkConfigOffset() {
        return PE.findString(PE.section[0].FileOffset, PE.getSize() - PE.getOverlaySize(), ".NETFramework,Version=v");
    }

    function getNetConfigStringByOffset(configOffset) {
        var result = PE.getString(configOffset).split("=")[1];

        if (result && result[0] !== 'v' && result.length > 7)
            result = String();

        result = result.substr(1);

        return File.cleanString(result);
    }

    if (PE.isNet()) {

        const netFrameworkConfigPattern = findNetFrameworkConfigOffset();

        if (netFrameworkConfigPattern != -1) {

            dotNetLibraryName = ".NET Framework"; // .NET Framework better than .NET Core
            dotNetLibraryVersion = String(getNetConfigStringByOffset(netFrameworkConfigPattern));

            if (dotNetLibraryVersion) {
                // antifake
                if (dotNetLibraryVersion.length >= 4 &&
                    dotNetLibraryVersion[1] !== "4" &&
                    dotNetLibraryVersion[1] !== "3" &&
                    dotNetLibraryVersion[1] !== "2" &&
                    dotNetLibraryVersion[2] !== "." &&
                    isNaN(Number(dotNetLibraryVersion[3]))) {
                    dotNetLibraryVersion = String();
                }
            }

        } else if (PE.isRichSignaturePresent() && PE.isTLSPresent()) {
            const netCoreConfigPattern = findNetCoreConfigOffset();

            if (netCoreConfigPattern != -1 && PE.compare("18", netCoreConfigPattern - 1) && PE.getNETVersion().substr(0, 4) === "v4.0") { // Is .NET Core DLL
                dotNetLibraryName = ".NET Core";
                dotNetLibraryVersion = getNetConfigStringByOffset(netCoreConfigPattern); // antifake
                if (dotNetLibraryVersion.length >= 2 && isNaN(Number(dotNetLibraryVersion[1]))) {
                    dotNetLibraryVersion = String();
                }
            }

        }

        dotNetLibraryVersion = File.cleanString(dotNetLibraryVersion); // remove strange symbols

        if (PE.isSignaturePresent(0x00, PE.getSize(), "'.NETCoreApp'")) {
            dotNetLibraryName = ".NET Core";
        } else if (!dotNetLibraryName) {
            dotNetLibraryName = ".NET Framework";
        }

        var clrVersion = File.cleanString(PE.getNETVersion());

        clrVersion = clrVersion.substring(1, clrVersion.length);

        dotNetLibraryVersion += (dotNetLibraryVersion ? ", " : String()) + "CLR " + clrVersion;

        // dotNetLibraryVersion = PE.getNETVersion();

        if (PE.compare("'MZ'90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000....00000E1FBA0E00B409CD21B8014CCD21'This program cannot be run in DOS mode.\r\r\n$'00000000")) {
            linkerName = "Microsoft Linker";
        }
    } else {
        var isNetNative = false;

        var rdataSection = PE.section[".rdata"];

        if (rdataSection &&
            PE.isFunctionPresent("LoadLibraryExW") &&
            PE.isFunctionPresent("ShellExecuteW") &&
            PE.findString(rdataSection.FileOffset, rdataSection.FileSize, "__clrcall") !== -1 && (
                PE.isSignatureInSectionPresent(rdataSection.Number, "002E004E0045005400200043006F00720065") ||
                PE.isSignatureInSectionPresent(rdataSection.Number, "2E004E00450054002000520075006E00740069006D006500")
            )
        ) {
            dotNetLibraryVersion = "Loader";
        }

        const dotNetDebugHeaderName = "DotNetRuntimeDebugHeader";

        var secondSection = PE.section[1]; // By index, can be ".rdata" or ".managed"

        // Checking for signs of .NET Native debug information
        var isDotNetRuntimeDebugBuild = (
            secondSection && (
                PE.isExportFunctionPresent(dotNetDebugHeaderName) || (
                    PE.compare("48 8d 05", secondSection.FileOffset) && ( // .managed, debug
                        PE.section[".managed"] || // .NET ~8.X
                        PE.section["hydrated"]
                    )
                )
            )
        );

        // General PE format check
        if (PE.compareEP("48") &&
            PE.compare("90", PE.getEntryPointOffset() - 1) && // NOP before OEP
            PE.isRichSignaturePresent() &&
            PE.getExportSection() !== -1 && // EAT always present
            PE.getNumberOfSections() >= 6) { // PE.isLibraryPresentExp(/^api-ms-win-crt-.*\.dll$/)
            if (isDotNetRuntimeDebugBuild || (
                PE.isSignatureInSectionPresent(secondSection.Number, "'System.' %% %% %% %% %% %%") && (
                    PE.isSignatureInSectionPresent(secondSection.Number, "'DOTNET_' %%") || // .rdata, release
                    PE.isSignatureInSectionPresent(secondSection.Number, "'D'00'O'00'T'00'N'00'E'00'T'00'_'") // .rdata, release (.NET 10)
                )
            )) {
                isNetNative = true;

                if (isDotNetRuntimeDebugBuild) {
                    dotNetLibraryOptions = "debug";
                } else {
                    dotNetLibraryOptions = "release";
                }

                if (PE.section[0].Name !== ".text" || (secondSection.Name !== ".rdata" && secondSection.Name !== ".managed") || (
                    !PE.isDll() && // executable?
                    PE.getNumberOfExports() === 1 && // only one export
                    PE.getExportFunctionName(0) !== dotNetDebugHeaderName // and it's not DotNetRuntimeDebugHeader
                )) {
                    dotNetLibraryOptions = dotNetLibraryOptions.append("modified");
                }
            }

            // TODO: Improve & add .NET 10 support (!!!!!!)
            const netCoreConfigPattern = findNetCoreConfigOffset();

            if (netCoreConfigPattern != -1) dotNetLibraryVersion = getNetConfigStringByOffset(netCoreConfigPattern);
        }

        if (dotNetLibraryVersion !== String() || dotNetLibraryOptions !== String()) dotNetLibraryName = ".NET " + (isNetNative ? "Native" : "Core");

        if (isNetNative) {
            _setLang("Native MSIL/C#");
        }
    }

    //
    // ==================================================
    //




    var isCppDetected = false,
        hasWideMainFunction = 0;

    msvcRuntimeLibrary = PE.isLibraryPresentExp(/^MSVCR/i);

    if (msvcRuntimeLibrary) {
        hasWideMainFunction = PE.isLibraryFunctionPresent(msvcRuntimeLibrary[0], "__wgetmainargs");
    }

    if (!PE.is64()) {
        if (PE.compareEP("558BEC51C745FC01000000837D0C007510833D")) {
            if (PE.compareEP("00", -4)) {
                sOptions = mfcLibraryOptions.append("libcd");
            } else if (PE.compareEP("00", -8)) {
                sOptions = mfcLibraryOptions.append("libcmtd");
            } else {
                sOptions = mfcLibraryOptions.append("msvcrtd");
            }
            cppCompilerVersion = "12.00";
            isCppDetected = true;
        } else if (PE.compareEP("558BEC538B5D08568B750C578B7D1085F67509833D")) {
            if (PE.compareEP("CA", -1)) {
                cppCompilerOptions = cppCompilerOptions.append("libc");
            } else if (PE.compareEP("59", -7)) {
                cppCompilerOptions = cppCompilerOptions.append("libcmt");
            } else {
                cppCompilerOptions = cppCompilerOptions.append("msvcrt");
            }
            cppCompilerVersion = "12.00";
            isCppDetected = true;
        } else if (PE.compareEP("558BEC6AFF68........68........64A100000000506489250000000083")) {
            var mainFunctionOffset;
            switch (PE.readByte(PE.getEntryPointOffset() + 31)) {
                case 0x10:
                    if (PE.compareEP("83", 107)) {
                        cppCompilerOptions = cppCompilerOptions.append("libc");
                        mainFunctionOffset = 116;
                    } else {
                        cppCompilerOptions = cppCompilerOptions.append("libcmt");
                        mainFunctionOffset = 133;
                    }
                    if (PE.compareEP("E8", mainFunctionOffset)) {
                        cppCompilerOptions = cppCompilerOptions.append("wmain");
                        --mainFunctionOffset;
                    }
                    if (PE.compareEP("FF", mainFunctionOffset + 25)) {
                        cppCompilerOptions = cppCompilerOptions.append("glob");
                    }
                    break;
                case 0x20:
                    cppCompilerOptions = cppCompilerOptions.append("msvcrt");
                    if (hasWideMainFunction) {
                        cppCompilerOptions = cppCompilerOptions.append("wmain");
                    }
                    if (PE.compareEP("FF", 109)) {
                        cppCompilerOptions = cppCompilerOptions.append("glob");
                    }
                    break;
                case 0x58:
                    if (PE.compareEP("33", 87)) {
                        cppCompilerOptions = cppCompilerOptions.append("libc");
                        mainFunctionOffset = 116;
                    } else {
                        cppCompilerOptions = cppCompilerOptions.append("libcmt");
                        mainFunctionOffset = 134;
                    }
                    if (PE.compareEP("E8", mainFunctionOffset)) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    break;
                case 0x68:
                    cppCompilerOptions = cppCompilerOptions.append("msvcrt");
                    if (PE.compareEP("5F", 45)) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    break;
                case 0x90:
                    cppCompilerOptions = cppCompilerOptions.append("libcd");
                    if (PE.compareEP("E8", 241)) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    break;
                case 0x94:
                    cppCompilerOptions = cppCompilerOptions.append("msvcrtd");
                    if (PE.compareEP("83", 233)) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    break;
                case 0xA4:
                    if (PE.compareEP("00", 125)) {
                        cppCompilerOptions = cppCompilerOptions.append("libcd");
                        mainFunctionOffset = 160;
                    } else {
                        cppCompilerOptions = cppCompilerOptions.append("libcmtd");
                        mainFunctionOffset = 179;
                    }
                    if (PE.compareEP("E8", mainFunctionOffset)) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    break;
                case 0xE0:
                    switch (PE.readByte(PE.getEntryPointOffset() + 38)) {
                        case 0xB8:
                            cppCompilerOptions = cppCompilerOptions.append("libcd");
                            if (PE.compareEP("E8", 241)) {
                                cppCompilerOptions = cppCompilerOptions.append("wmain");
                            }
                            break;
                        case 0xC7:
                            cppCompilerOptions = cppCompilerOptions.append("msvcrtd");
                            if (hasWideMainFunction) {
                                cppCompilerOptions = cppCompilerOptions.append("wmain");
                            }
                            if (PE.compareEP("FF", 121)) {
                                cppCompilerOptions = cppCompilerOptions.append("glob");
                            }
                            break;
                    }
                    break;
                case 0xE8:
                    cppCompilerOptions = cppCompilerOptions.append("libcd");
                    break;
                case 0xF0:
                    if (PE.compareEP("00", 125)) {
                        cppCompilerOptions = cppCompilerOptions.append("libcd");
                        mainFunctionOffset = 160;
                    } else {
                        cppCompilerOptions = cppCompilerOptions.append("libcmtd");
                        mainFunctionOffset = 179;
                    }
                    if (PE.compareEP("E8", mainFunctionOffset)) {
                        cppCompilerOptions = cppCompilerOptions.append("wmain");
                        --mainFunctionOffset;
                    }
                    if (PE.compareEP("FF", mainFunctionOffset + 25)) {
                        cppCompilerOptions = cppCompilerOptions.append("glob");
                    }
                    break;
            }
            cppCompilerVersion = "11.00-13.10";
            isCppDetected = true;
        } else if (PE.compareEP("6A0C68........E8........33C0408945E48B750C33FF3BF7750C393D")) {
            switch (PE.readByte(PE.getEntryPointOffset() - 1)) {
                case 0xC0:
                    cppCompilerOptions = cppCompilerOptions.append("libc");
                    break;
                case 0x00:
                    cppCompilerOptions = cppCompilerOptions.append("libcmt");
                    break;
            }
            cppCompilerVersion = "13.10";
            isCppDetected = true;
        } else if (PE.compareEP("6A..68........E8........66813D")) {
            cppCompilerVersion = "13.10";
            isCppDetected = true;
        } else if (PE.compareEP("6A..68........E8........BF940000008BC7E8")) {
            mainFunctionOffset = 0;
            var mainFunctionType;
            switch (PE.readByte(PE.getEntryPointOffset() + 1)) {
                case 0x18:
                    mainFunctionType = "wmain";
                    mainFunctionOffset = 197;
                    break;
                case 0x60:
                    mainFunctionType = "wWinMain";
                    mainFunctionOffset = 199;
                    break;
            }
            if (mainFunctionOffset) {
                if (PE.compareEP("6A", mainFunctionOffset)) {
                    cppCompilerOptions = cppCompilerOptions.append("libcmt");
                    mainFunctionOffset += 62;
                } else {
                    cppCompilerOptions = cppCompilerOptions.append("libc");
                    mainFunctionOffset += 69;
                }
                if (PE.compareEP("E8", mainFunctionOffset)) {
                    cppCompilerOptions = cppCompilerOptions.append(mainFunctionType);
                }
            }
            cppCompilerVersion = "13.10";
            isCppDetected = true;
        } else if (PE.compareEP("8BFF558BEC837D0C017505E8")) {
            if (PE.compareEP("8B", 16)) {
                cppCompilerOptions = cppCompilerOptions.append(PE.compareEP("E8", 74) ? "libcmtd" : "msvcrtd");
            } else {
                cppCompilerOptions = cppCompilerOptions.append(PE.compareEP("8B", 35) ? "libcmt" : "msvcrt");
            }
            cppCompilerVersion = "15.00-16.00";
            isCppDetected = true;
        } else if (PE.compareEP("8BFF558BECE8......00E8......005DC3")) {
            switch (PE.readByte(PE.getEntryPointOffset() + 58)) {
                case 0x88:
                    cppCompilerOptions = cppCompilerOptions.append("msvcrtd", "wWinMain");
                    cppCompilerVersion = "15.00";
                    break;
                case 0x8C:
                    cppCompilerOptions = cppCompilerOptions.append("msvcrtd");
                    cppCompilerVersion = "15.00";
                    break;
                case 0x90:
                    cppCompilerOptions = cppCompilerOptions.append("msvcrtd");
                    if (hasWideMainFunction) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    cppCompilerVersion = "16.00";
                    break;
                case 0x94:
                    cppCompilerOptions = cppCompilerOptions.append("libcmtd");
                    if (PE.compareEP("52", 145)) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    cppCompilerVersion = "15.00";
                    break;
                case 0x98:
                    cppCompilerOptions = cppCompilerOptions.append("libcmtd");
                    if (PE.compareEP("6A", 645)) {
                        cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                    }
                    cppCompilerVersion = "16.00";
                    break;
                case 0xE4:
                    cppCompilerOptions = cppCompilerOptions.append("msvcrtd");
                    if (hasWideMainFunction) {
                        cppCompilerOptions = cppCompilerOptions.append("wmain");
                    }
                    if (PE.compareEP("FF", -0x9B)) {
                        cppCompilerOptions = cppCompilerOptions.append("glob");
                    }
                    cppCompilerVersion = "15.00-16.00";
                    break;
                case 0xE8:
                    cppCompilerOptions = cppCompilerOptions.append("libcmtd");
                    if (PE.compareEP("E8", 92)) {
                        if (PE.compareEP("E8", 184)) {
                            cppCompilerOptions = cppCompilerOptions.append("wmain");
                            hasWideMainFunction = 1;
                        }
                        cppCompilerVersion = "15.00";
                    } else {
                        if (PE.compareEP("E8$$$$$$$$8BFF558BEC83EC10", 213)) {
                            cppCompilerOptions = cppCompilerOptions.append("wmain");
                            hasWideMainFunction = 1;
                        }
                        cppCompilerVersion = "16.00";
                    }
                    if (hasWideMainFunction) {
                        if (PE.compareEP("10", -6)) {
                            cppCompilerOptions = cppCompilerOptions.append("glob");
                        }
                    } else {
                        if (PE.compareEP("CC", -2)) {
                            cppCompilerOptions = cppCompilerOptions.append("glob");
                        }
                    }
                    break;
            }
            isCppDetected = true;
        } else if (PE.compareEP("E8......00E9$$$$$$$$6A..68........E8")) {
            var nEP = PE.getEntryPointOffset();
            nEP += 10 + ~~PE.readDword(nEP + 6);
            if (PE.compare("10", nEP + 1)) {
                cppCompilerOptions = cppCompilerOptions.append("msvcrt");
                if (hasWideMainFunction) {
                    cppCompilerOptions = cppCompilerOptions.append("wmain");
                }
                if (PE.compareEP("FF", -48)) {
                    cppCompilerOptions = cppCompilerOptions.append("glob");
                }
            } else if (PE.compare("33DB", nEP + 12)) {
                cppCompilerOptions = cppCompilerOptions.append("msvcrt");
                if (PE.compare("89", nEP + 53) || PE.compare("E0", nEP + 60)) {
                    cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                }
            } else if (PE.compare("3935", nEP + 14)) {
                cppCompilerOptions = cppCompilerOptions.append("libcmt");
                if (PE.compareEP("E8$$$$$$$$8B", -150)) {
                    cppCompilerOptions = cppCompilerOptions.append("wmain");
                }
                if (PE.compareEP("FF", -0xA3)) {
                    cppCompilerOptions = cppCompilerOptions.append("glob");
                }
            } else if (PE.compare("8D4598", nEP + 12)) {
                cppCompilerOptions = cppCompilerOptions.append("libcmt");
                if (PE.compareEP("51", 15)) {
                    cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                }
            } else if (PE.compare("33F68975FC", nEP + 12)) {
                cppCompilerOptions = cppCompilerOptions.append("libcmt");
                if (PE.compare("E8", nEP + 170)) {
                    cppCompilerOptions = cppCompilerOptions.append("wWinMain");
                }
            } else if (PE.compare("B8'MZ'", nEP + 12)) {
                cppCompilerOptions = cppCompilerOptions.append("libcmt");
                if (PE.compare("E8", nEP + 149)) {
                    cppCompilerOptions = cppCompilerOptions.append("wmain");
                    --nEP;
                }
                if (PE.compare("FF", nEP + 174)) {
                    cppCompilerOptions = cppCompilerOptions.append("glob");
                }
            }
            cppCompilerVersion = "15.00-16.00";
            isCppDetected = true;
        } else if (PE.compareEP("64A100000000558BEC6AFF68")) {
            isCppDetected = true;
        } else if (PE.compareEP("64A100000000506489250000000083C4A8535657")) {
            cppCompilerVersion = "11.00";
            isCppDetected = true;
        } else if (PE.compareEP("535657BB........8B......553BFB75")) {
            cppCompilerVersion = "8.00";
            isCppDetected = true;
        } else if (PE.compareEP("56E8........8BF0E8........68........68........E8........6A..68........56E8")) {
            cppCompilerVersion = "8.00";
            isCppDetected = true;
        } else if (PE.compareEP("53B8........8B......565785DB5575")) {
            cppCompilerVersion = "10.20";
            isCppDetected = true;
        } else if (PE.compareEP("558BEC83EC4456FF15........6A018BF0FF15")) {
            cppCompilerVersion = "12.00";
            isCppDetected = true;
        } else if (PE.compareEP("558BEC83EC4456FF15........8BF08A063C22")) {
            cppCompilerVersion = "12.00";
            isCppDetected = true;
        } else if (PE.compareEP("558D6C....81EC........8B45..83F801560F84........85C00F84")) {
            cppCompilerVersion = "12.00";
            isCppDetected = true;
        }
        // else if(PE.compareEP("837C24080175098B442404A3....0010E88BFFFFFF")) { // Pure Basic 4.0
        //     cppCompilerVersion = "12.00";
        //     isCppDetected = true;
        // }
        else if (PE.compareEP("558BEC538B5D08568B750C85F6578B7D10")) {
            cppCompilerVersion = "13.00";
            isCppDetected = true;
        } else if (PE.compareEP("833D........00741A68........E8........85C059740BFF742404FF15........59E8........68........68........E8........85C059597554565768........E8........BE........8BC6BF")) {
            cppCompilerVersion = "14.00";
            isCppDetected = true;
        } else if (PE.compareEP("6A1468........E8........BB94000000536A008B..........FFD750FF..........8BF085F6750A6A12E8........59EB18891E56FF..........5685C0751450FFD750FF..........B8")) {
            cppCompilerVersion = "14.00";
            isCppDetected = true;
        } else if (PE.compareEP("8BFF558BEC538B5D08568B750C85F6578B7D100F84....000083FE01")) {
            cppCompilerVersion = "14.00";
            isCppDetected = true;
        } else if (PE.compareEP("8BFF558BEC538B5D08568B750C85F6578B7D107509833D........00EB2683FE01740583FE027522A1........85C07409575653FFD085C0740C575653E8......FF85C0750433C0EB4E575653E8......FF83FE0189450C750C85C07537575053E8......FF85F6740583FE037526575653E8......FF85C0750321450C837D0C007411A1........85C07408575653FFD089450C8B450C5F5E5B5DC20C00")) {
            cppCompilerVersion = "14.00";
            isCppDetected = true;
        } else if (PE.compareEP("558BEC83EC10A1........8365F8008365FC005357BF4EE640BB3BC7BB0000FFFF740D85C37409F7D0A3........EB60568D45F850FF15........8B75FC3375F8FF15........33F0FF15........33F0FF15........33F08D45F050FF15........8B45F43345F033F03BF77507BE4FE640BBEB0B85F375078BC6C1E0100BF08935........F7D68935........5E5F5BC9C3")) {
            cppCompilerVersion = "14.00";
            isCppDetected = true;
        } else if (PE.compareEP("558BEC83EC245356578965F8")) {
            isCppDetected = true;
        }
    } else {
        if (PE.compareEP("4883EC2885D248895C243048896C243848897424408BDA488BE9498BF0751E3915")) {
            cppCompilerVersion = "14.00"; // DLL
            isCppDetected = true;
        } else if (PE.compareEP("4883EC5848895C247048897C247866813D")) {
            cppCompilerVersion = "14.00"; // console, msvcrt
            isCppDetected = true;
        } else if (PE.compareEP("4883EC3848895C245048897C2458FF15")) {
            cppCompilerVersion = "14.00"; // console, static
            isCppDetected = true;
        } else if (PE.compareEP("488BC44881EC........4889581848897820488D4888FF15")) {
            cppCompilerVersion = "14.00"; // GUI
            isCppDetected = true;
        } else if (PE.compareEP("4883EC28E8........4883C428E9$$$$$$$$48895C24")) {
            cppCompilerVersion = "16.00";
            isCppDetected = true;
        } else if (PE.compareEP("4883EC28E8........E8........4883C428C3")) {
            cppCompilerVersion = "16.00"; // debug
            isCppDetected = true;
        } else if (PE.compareEP("48895C24084889742410574883EC20498BF88BDA488BF183FA017505E8")) {
            cppCompilerVersion = "16.00"; // DLL
            isCppDetected = true;
        } else if (PE.compareEP("4C894424188954241048894C24084883EC28837C2438017505E8")) {
            cppCompilerVersion = "16.00"; // DLL debug
            isCppDetected = true;
        }
    }

    if (isCppDetected) {
        cppCompilerName = "Microsoft Visual C/C++";
    }

    if (PE.isRichSignaturePresent()) {
        linkerName = "Microsoft Linker";
    }

    var mfcLibraryMatch = PE.isLibraryPresentExp(/^MFC(\d+?)(u?)(d?)\.dll/i);

    if (mfcLibraryMatch) {
        mfcLibraryVersion = (mfcLibraryMatch[1] / 10).toFixed(1);

        if (mfcLibraryMatch[2]) {
            mfcLibraryOptions = "Unicode";
        }

        if (mfcLibraryMatch[3]) {
            mfcLibraryOptions = mfcLibraryOptions.append("debug");
        }

        mfcLibraryName = "MFC";
    }

    if (PE.isDeepScan() && (mfcLibraryName == String())) {
        var dataSection = PE.section[".data"];

        if (dataSection && PE.isSignatureInSectionPresent(dataSection.Number, "'CMFCComObject'")) {
            mfcLibraryName = "MFC";
            mfcLibraryOptions = "static";
        }
    }

    if (PE.isNet()) {
        if (PE.isNetObjectPresent("Microsoft.VisualBasic")) {
            vbCompilerName = "VB.NET";
            vbDetected = true;
        }
    } else if (PE.isLibraryPresentExp(/^MSVBVM60(\.DLL)?/i)) {
        vbCompilerName = "Microsoft Visual Basic";
        vbCompilerVersion = "6.0";
        vbCompilerOptions = getVbOptions();
    } else if (PE.isLibraryPresentExp(/^MSVBVM50(\.DLL)?/i)) {
        vbCompilerName = "Microsoft Visual Basic";
        vbCompilerVersion = "5.0";
        vbCompilerOptions = getVbOptions();
    } else if (PE.isLibraryPresentExp(/^VB40032(\.DLL)/i)) {
        vbCompilerName = "Microsoft Visual Basic";
        vbCompilerVersion = "4.0";
    }

    if (vbCompilerVersion && (
        PE.isLibraryPresentExp(/^(VB40032|MSVBVM[56]0)$/i) ||
        (vbCompilerVersion === "6.0" && !PE.isRichSignaturePresent())
    )) {
        vbCompilerOptions = vbCompilerOptions.append("modified/patched");
    }

    // Rich
    var richLinkerName = String(),
        richLinkerVersion = String(),
        richLinkerOptions = String(),
        richCppCompilerName = String(),
        richCppCompilerVersion = String(),
        richCppCompilerOptions = String(),
        richMasmCompilerName = String(),
        richMasmCompilerVersion = String(),
        richMasmCompilerOptions = String(),
        richVbCompilerName = String(),
        richVbCompilerVersion = String(),
        richVbCompilerOptions = String();

    for (var i = PE.getNumberOfRichIDs() - 1; i >= 0; i--) {
        var richId = PE.getRichID(i);

        if (richId > 1) {
            var richVersion = String(),
                richOptions = String(),
                isLinker = 0,
                isCompiler = 0,
                isMasm = 0,
                isBasic = 0;

            var richIdMap = {
                0x0002: { isLinker: 1, richVersion: "5.10" },
                0x0004: { isLinker: 1, richVersion: "6.00" },
                0x0007: { isBasic: 1, richVersion: "5.00", richOptions: "Native" },
                0x0008: { isCompiler: 1, richVersion: "11.00", richOptions: "C/C++" },
                0x0009: { isBasic: 1, richVersion: "6.00", richOptions: "Native" },
                0x000a: { isCompiler: 1, richVersion: "12.00", richOptions: "C" },
                0x000b: { isCompiler: 1, richVersion: "12.00", richOptions: "C++" },
                0x000e: { isMasm: 1, richVersion: "6.13" },
                0x000f: { isMasm: 1, richVersion: "7.01" },
                0x0010: { isLinker: 1, richVersion: "5.11" },
                0x0012: { isMasm: 1, richVersion: "6.14", richOptions: "MMX2 support" },
                0x0013: { isLinker: 1, richVersion: "5.12" },
                0x0015: { isCompiler: 1, richVersion: "12.00", richOptions: "C/std" },
                0x0016: { isCompiler: 1, richVersion: "12.00", richOptions: "C++/std" },
                0x0017: { isCompiler: 1, richVersion: "12.00", richOptions: "C/book" },
                0x0018: { isCompiler: 1, richVersion: "12.00", richOptions: "C++/book" },
                0x001b: { isBasic: 1, richVersion: "7.00", richOptions: "Native" },
                0x001c: { isCompiler: 1, richVersion: "13.00", richOptions: "C" },
                0x001d: { isCompiler: 1, richVersion: "13.00", richOptions: "C++" },
                0x001e: { isLinker: 1, richVersion: "6.10" },
                0x0020: { isLinker: 1, richVersion: "6.01" },
                0x0022: { isBasic: 1, richVersion: "6.10", richOptions: "Native" },
                0x0023: { isCompiler: 1, richVersion: "12.10", richOptions: "C" },
                0x0024: { isCompiler: 1, richVersion: "12.10", richOptions: "C++" },
                0x0025: { isLinker: 1, richVersion: "6.20" },
                0x0028: { isLinker: 1, richVersion: "6.21" },
                0x002a: { isMasm: 1, richVersion: "6.15" },
                0x002b: { isCompiler: 1, richVersion: "13.00", richOptions: "LTCG/C" },
                0x002c: { isCompiler: 1, richVersion: "13.00", richOptions: "LTCG/C++" },
                0x002d: { isMasm: 1, richVersion: "6.20" },
                0x002f: { isBasic: 1, richVersion: "6.20", richOptions: "Native" },
                0x0030: { isCompiler: 1, richVersion: "12.20", richOptions: "C" },
                0x0031: { isCompiler: 1, richVersion: "12.20", richOptions: "C++" },
                0x0032: { isCompiler: 1, richVersion: "12.20", richOptions: "C/std" },
                0x0033: { isCompiler: 1, richVersion: "12.20", richOptions: "C++/std" },
                0x0034: { isCompiler: 1, richVersion: "12.20", richOptions: "C/book" },
                0x0035: { isCompiler: 1, richVersion: "12.20", richOptions: "C++/book" },
                0x0039: { isCompiler: 1, richVersion: "13.00", richOptions: "C/std" },
                0x003a: { isCompiler: 1, richVersion: "13.00", richOptions: "C++/std" },
                0x003c: { isLinker: 1, richVersion: "6.22" },
                0x003d: { isLinker: 1, richVersion: "7.00" },
                0x0040: { isMasm: 1, richVersion: "7.00" },
                0x0041: { isCompiler: 1, richVersion: "13.00", richOptions: "POGO_I_C" },
                0x0042: { isCompiler: 1, richVersion: "13.00", richOptions: "POGO_I_CPP" },
                0x0043: { isCompiler: 1, richVersion: "13.00", richOptions: "POGO_O_C" },
                0x0044: { isCompiler: 1, richVersion: "13.00", richOptions: "POGO_O_CPP" },
                0x0047: { isLinker: 1, richVersion: "7.10p" },
                0x004b: { isMasm: 1, richVersion: "7.10p" },
                0x004c: { isCompiler: 1, richVersion: "13.10p", richOptions: "C" },
                0x004d: { isCompiler: 1, richVersion: "13.10p", richOptions: "C++/book" },
                0x004e: { isCompiler: 1, richVersion: "13.10p", richOptions: "C/std" },
                0x004f: { isCompiler: 1, richVersion: "13.10p", richOptions: "C++/std" },
                0x0050: { isCompiler: 1, richVersion: "13.10p", richOptions: "LTCG/C" },
                0x0051: { isCompiler: 1, richVersion: "13.10p", richOptions: "LTCG/C++" },
                0x0052: { isCompiler: 1, richVersion: "13.10p", richOptions: "POGO_I_C" },
                0x0053: { isCompiler: 1, richVersion: "13.10p", richOptions: "POGO_I_C" },
                0x0054: { isCompiler: 1, richVersion: "13.10p", richOptions: "POGO_O_C" },
                0x0055: { isCompiler: 1, richVersion: "13.10p", richOptions: "POGO_O_CPP" },
                0x0056: { isLinker: 1, richVersion: "6.24" },
                0x005a: { isLinker: 1, richVersion: "7.10" },
                0x005f: { isCompiler: 1, richVersion: "13.10", richOptions: "C" },
                0x0060: { isCompiler: 1, richVersion: "13.10", richOptions: "C++/book" },
                0x0061: { isCompiler: 1, richVersion: "13.10", richOptions: "C/std" },
                0x0062: { isCompiler: 1, richVersion: "13.10", richOptions: "C++/std" },
                0x0063: { isCompiler: 1, richVersion: "13.10", richOptions: "LTCG/C" },
                0x0064: { isCompiler: 1, richVersion: "13.10", richOptions: "LTCG/C++" },
                0x0065: { isCompiler: 1, richVersion: "13.10", richOptions: "POGO_I_C" },
                0x0066: { isCompiler: 1, richVersion: "13.10", richOptions: "POGO_I_C" },
                0x0067: { isCompiler: 1, richVersion: "13.10", richOptions: "POGO_O_C" },
                0x0068: { isCompiler: 1, richVersion: "13.10", richOptions: "POGO_O_CPP" },
                0x006d: { isCompiler: 1, richVersion: "14.00", richOptions: "C" },
                0x006e: { isCompiler: 1, richVersion: "14.00", richOptions: "C++/book" },
                0x006f: { isCompiler: 1, richVersion: "14.00", richOptions: "C/std" },
                0x0070: { isCompiler: 1, richVersion: "14.00", richOptions: "C++/std" },
                0x0071: { isCompiler: 1, richVersion: "14.00", richOptions: "LTCG/C" },
                0x0072: { isCompiler: 1, richVersion: "14.00", richOptions: "LTCG/C++" },
                0x0073: { isCompiler: 1, richVersion: "14.00", richOptions: "POGO_I_C" },
                0x0074: { isCompiler: 1, richVersion: "14.00", richOptions: "POGO_I_C" },
                0x0075: { isCompiler: 1, richVersion: "14.00", richOptions: "POGO_O_C" },
                0x0076: { isCompiler: 1, richVersion: "14.00", richOptions: "POGO_O_CPP" },
                0x0078: { isLinker: 1, richVersion: "8.00" },
                0x007d: { isMasm: 1, richVersion: "8.00" },
                0x0080: { isCompiler: 1, richVersion: "14.00", richOptions: "CVTCIL/C" },
                0x0081: { isCompiler: 1, richVersion: "14.00", richOptions: "CVTCIL/C++" },
                0x0082: { isCompiler: 1, richVersion: "14.00", richOptions: "LTCG/MSIL" },
                0x0083: { isCompiler: 1, richVersion: "15.00", richOptions: "C" },
                0x0084: { isCompiler: 1, richVersion: "15.00", richOptions: "C++" },
                0x0085: { isCompiler: 1, richVersion: "15.00", richOptions: "C/std" },
                0x0086: { isCompiler: 1, richVersion: "15.00", richOptions: "C++/std" },
                0x0087: { isCompiler: 1, richVersion: "15.00", richOptions: "CVTCIL/C" },
                0x0088: { isCompiler: 1, richVersion: "15.00", richOptions: "CVTCIL/C++" },
                0x0089: { isCompiler: 1, richVersion: "15.00", richOptions: "LTCG/C" },
                0x008a: { isCompiler: 1, richVersion: "15.00", richOptions: "LTCG/C++" },
                0x008b: { isCompiler: 1, richVersion: "15.00", richOptions: "LTCG/MSIL" },
                0x008c: { isCompiler: 1, richVersion: "15.00", richOptions: "POGO_I_C" },
                0x008d: { isCompiler: 1, richVersion: "15.00", richOptions: "POGO_I_C" },
                0x008e: { isCompiler: 1, richVersion: "15.00", richOptions: "POGO_O_C" },
                0x008f: { isCompiler: 1, richVersion: "15.00", richOptions: "POGO_O_CPP" },
                0x0091: { isLinker: 1, richVersion: "9.00" },
                0x0095: { isMasm: 1, richVersion: "9.00" },
                0x009d: { isLinker: 1, richVersion: "10.00" },
                0x009e: { isMasm: 1, richVersion: "10.00" },
                0x00aa: { isCompiler: 1, richVersion: "16.00", richOptions: "C" },
                0x00ab: { isCompiler: 1, richVersion: "16.00", richOptions: "C++" },
                0x00ac: { isCompiler: 1, richVersion: "16.00", richOptions: "CVTCIL/C" },
                0x00ad: { isCompiler: 1, richVersion: "16.00", richOptions: "CVTCIL/C++" },
                0x00ae: { isCompiler: 1, richVersion: "16.00", richOptions: "LTCG/C" },
                0x00af: { isCompiler: 1, richVersion: "16.00", richOptions: "LTCG/C++" },
                0x00b0: { isCompiler: 1, richVersion: "16.00", richOptions: "LTCG/MSIL" },
                0x00b1: { isCompiler: 1, richVersion: "16.00", richOptions: "POGO_I_C" },
                0x00b2: { isCompiler: 1, richVersion: "16.00", richOptions: "POGO_I_C" },
                0x00b3: { isCompiler: 1, richVersion: "16.00", richOptions: "POGO_O_C" },
                0x00b4: { isCompiler: 1, richVersion: "16.00", richOptions: "POGO_O_CPP" },
                0x00ba: { isLinker: 1, richVersion: "10.10" },
                0x00bb: { isMasm: 1, richVersion: "10.10" },
                0x00bc: { isCompiler: 1, richVersion: "16.10", richOptions: "C" },
                0x00bd: { isCompiler: 1, richVersion: "16.10", richOptions: "C++" },
                0x00be: { isCompiler: 1, richVersion: "16.10", richOptions: "CVTCIL/C" },
                0x00bf: { isCompiler: 1, richVersion: "16.10", richOptions: "CVTCIL/C++" },
                0x00c0: { isCompiler: 1, richVersion: "16.10", richOptions: "LTCG/C" },
                0x00c1: { isCompiler: 1, richVersion: "16.10", richOptions: "LTCG/C++" },
                0x00c2: { isCompiler: 1, richVersion: "16.10", richOptions: "LTCG/MSIL" },
                0x00c3: { isCompiler: 1, richVersion: "16.10", richOptions: "POGO_I_C" },
                0x00c4: { isCompiler: 1, richVersion: "16.10", richOptions: "POGO_I_C" },
                0x00c5: { isCompiler: 1, richVersion: "16.10", richOptions: "POGO_O_C" },
                0x00c6: { isCompiler: 1, richVersion: "16.10", richOptions: "POGO_O_CPP" },
                0x00cc: { isLinker: 1, richVersion: "11.00" },
                0x00cd: { isMasm: 1, richVersion: "11.00" },
                0x00ce: { isCompiler: 1, richVersion: "17.00", richOptions: "C" },
                0x00cf: { isCompiler: 1, richVersion: "17.00", richOptions: "C++" },
                0x00d0: { isCompiler: 1, richVersion: "17.00", richOptions: "CVTCIL/C" },
                0x00d1: { isCompiler: 1, richVersion: "17.00", richOptions: "CVTCIL/C++" },
                0x00d2: { isCompiler: 1, richVersion: "17.00", richOptions: "LTCG/C" },
                0x00d3: { isCompiler: 1, richVersion: "17.00", richOptions: "LTCG/C++" },
                0x00d4: { isCompiler: 1, richVersion: "17.00", richOptions: "LTCG/MSIL" },
                0x00d5: { isCompiler: 1, richVersion: "17.00", richOptions: "POGO_I_C" },
                0x00d6: { isCompiler: 1, richVersion: "17.00", richOptions: "POGO_I_C" },
                0x00d7: { isCompiler: 1, richVersion: "17.00", richOptions: "POGO_O_C" },
                0x00d8: { isCompiler: 1, richVersion: "17.00", richOptions: "POGO_O_CPP" },
                0x00de: { isLinker: 1, richVersion: "12.00" },
                0x00df: { isMasm: 1, richVersion: "12.00" },
                0x00e0: { isCompiler: 1, richVersion: "18.00", richOptions: "C" },
                0x00e1: { isCompiler: 1, richVersion: "18.00", richOptions: "C++" },
                0x00e2: { isCompiler: 1, richVersion: "18.00", richOptions: "CVTCIL/C" },
                0x00e3: { isCompiler: 1, richVersion: "18.00", richOptions: "CVTCIL/C++" },
                0x00e4: { isCompiler: 1, richVersion: "18.00", richOptions: "LTCG/C" },
                0x00e5: { isCompiler: 1, richVersion: "18.00", richOptions: "LTCG/C++" },
                0x00e6: { isCompiler: 1, richVersion: "18.00", richOptions: "LTCG/MSIL" },
                0x00e7: { isCompiler: 1, richVersion: "18.00", richOptions: "POGO_I_C" },
                0x00e8: { isCompiler: 1, richVersion: "18.00", richOptions: "POGO_I_C" },
                0x00e9: { isCompiler: 1, richVersion: "18.00", richOptions: "POGO_O_C" },
                0x00ea: { isCompiler: 1, richVersion: "18.00", richOptions: "POGO_O_CPP" },
                0x00f0: { isLinker: 1, richVersion: "12.10" },
                0x00f1: { isMasm: 1, richVersion: "12.10" },
                0x00f2: { isCompiler: 1, richVersion: "18.10", richOptions: "C" },
                0x00f3: { isCompiler: 1, richVersion: "18.10", richOptions: "C++" },
                0x00f4: { isCompiler: 1, richVersion: "18.10", richOptions: "CVTCIL/C" },
                0x00f5: { isCompiler: 1, richVersion: "18.10", richOptions: "CVTCIL/C++" },
                0x00f6: { isCompiler: 1, richVersion: "18.10", richOptions: "LTCG/C" },
                0x00f7: { isCompiler: 1, richVersion: "18.10", richOptions: "LTCG/C++" },
                0x00f8: { isCompiler: 1, richVersion: "18.10", richOptions: "LTCG/MSIL" },
                0x00f9: { isCompiler: 1, richVersion: "18.10", richOptions: "POGO_I_C" },
                0x00fa: { isCompiler: 1, richVersion: "18.10", richOptions: "POGO_I_C" },
                0x00fb: { isCompiler: 1, richVersion: "18.10", richOptions: "POGO_O_C" },
                0x00fc: { isCompiler: 1, richVersion: "18.10", richOptions: "POGO_O_CPP" },
                0x0102: { isLinker: 1, richVersion: "14.00" },
                0x0103: { isMasm: 1, richVersion: "14.00" },
                0x0104: { isCompiler: 1, richVersion: "19.00", richOptions: "C" },
                0x0105: { isCompiler: 1, richVersion: "19.00", richOptions: "C++" },
                0x0106: { isCompiler: 1, richVersion: "19.00", richOptions: "CVTCIL/C" },
                0x0107: { isCompiler: 1, richVersion: "19.00", richOptions: "CVTCIL/C++" },
                0x0108: { isCompiler: 1, richVersion: "19.00", richOptions: "LTCG/C" },
                0x0109: { isCompiler: 1, richVersion: "19.00", richOptions: "LTCG/C++" },
                0x010a: { isCompiler: 1, richVersion: "19.00", richOptions: "LTCG/MSIL" },
                0x010b: { isCompiler: 1, richVersion: "19.00", richOptions: "POGO_I_C" },
                0x010c: { isCompiler: 1, richVersion: "19.00", richOptions: "POGO_I_C" },
                0x010d: { isCompiler: 1, richVersion: "19.00", richOptions: "POGO_O_C" },
                0x010e: { isCompiler: 1, richVersion: "19.00", richOptions: "POGO_O_CPP" }
            };

            var richInfo = richIdMap[richId];
            if (richInfo) {
                isLinker = richInfo.isLinker || 0;
                isCompiler = richInfo.isCompiler || 0;
                isMasm = richInfo.isMasm || 0;
                isBasic = richInfo.isBasic || 0;
                richVersion = richInfo.richVersion || String();
                richOptions = richInfo.richOptions || String();
            }

            var formattedVersion = richVersion + "." + PE.getRichVersion(i);

            if (isLinker && richVersion == "14.00" || isMasm && richVersion == "14.00" || isCompiler && richVersion == "19.00") {
                var buildNumber = PE.getRichVersion(i);
                var minorVersion = 0;

                if (buildNumber > 25000) {
                    if (buildNumber < 25506) minorVersion = 10;
                    else if (buildNumber < 25830) minorVersion = 11;
                    else if (buildNumber < 26128) minorVersion = 12;
                    else if (buildNumber < 26428) minorVersion = 13;
                    else if (buildNumber < 26726) minorVersion = 14;
                    else if (buildNumber < 26926) minorVersion = 15;
                    else if (buildNumber < 27508) minorVersion = 16;
                    else if (buildNumber < 27702) minorVersion = 20;
                    else if (buildNumber < 27905) minorVersion = 21;
                    else if (buildNumber < 28105) minorVersion = 22;
                    else if (buildNumber < 28314) minorVersion = 23;
                    else if (buildNumber < 28610) minorVersion = 24;
                    else if (buildNumber < 28805) minorVersion = 25;
                    else if (buildNumber < 29110) minorVersion = 26;
                    else if (buildNumber < 29333) minorVersion = 27;
                    else if (buildNumber < 30133) minorVersion = 28;
                    else if (buildNumber < 30401) minorVersion = 29;
                    else if (buildNumber < 30818) minorVersion = 30;
                    else if (buildNumber < 31114) minorVersion = 31;
                    else if (buildNumber < 31424) minorVersion = 32;
                    else if (buildNumber < 31721) minorVersion = 33;
                    else if (buildNumber < 32019) minorVersion = 34;
                    else if (buildNumber < 32019) minorVersion = 34;
                    else if (buildNumber < 32323) minorVersion = 35;
                    else if (buildNumber < 32532) minorVersion = 36;  // VS 2022 17.6.x
                    else if (buildNumber < 32543) minorVersion = 36;  // VS 2022 17.6.x (14.36.32532-14.36.32535)
                    else if (buildNumber < 32822) minorVersion = 36;  // VS 2022 17.7.0 (14.36.32543)
                    else if (buildNumber < 33130) minorVersion = 37;  // VS 2022 17.7.x
                    else if (buildNumber < 33520) minorVersion = 38;  // VS 2022 17.8.0 (14.38.33135)
                    else if (buildNumber < 33811) minorVersion = 39;  // VS 2022 17.9.x (14.39.33520-14.39.33523)
                    else if (buildNumber < 34120) minorVersion = 40;  // VS 2022 17.10.x (14.40.33811-14.40.33818)
                    else if (buildNumber < 34436) minorVersion = 41;  // VS 2022 17.11.0 (14.41.34120)
                    else if (buildNumber < 34808) minorVersion = 42;  // VS 2022 17.12.4 (14.42.34436)
                    else if (buildNumber < 35000) minorVersion = 43;  // VS 2022 17.13.x (14.43.34808-14.43.34810)
                    else if (buildNumber < 35224) minorVersion = 44;  // VS 2022 17.14.x (14.44.35207-14.44.35223)
                    else if (buildNumber < 36000) minorVersion = 50;  // VS 2026 18.0.x-18.3.x (14.50.35503-14.50.35724)
                    else if (buildNumber < 37000) minorVersion = 51;  // VS 2026 18.0.4 (14.51.36014)
                    else minorVersion = 51;  // Future versions
                }

                if (minorVersion) {
                    if (isLinker || isMasm) {
                        formattedVersion = "14." + minorVersion + "." + buildNumber;
                    } else if (isCompiler) {
                        formattedVersion = "19." + minorVersion + "." + buildNumber;
                    }
                }
            }

            if (isLinker) {
                if (formattedVersion > richLinkerVersion) {
                    richLinkerName = "Microsoft Linker";
                    richLinkerVersion = formattedVersion;
                    richLinkerOptions = richOptions;
                }
            } else if (isCompiler) {
                if (formattedVersion > richCppCompilerVersion) {
                    richCppCompilerName = "Microsoft Visual C/C++";
                    richCppCompilerVersion = formattedVersion;
                    richCppCompilerOptions = richOptions;
                }
            } else if (isMasm) {
                if (formattedVersion > richMasmCompilerVersion) {
                    richMasmCompilerName = "MASM";
                    richMasmCompilerVersion = formattedVersion;
                    richMasmCompilerOptions = richOptions;
                }
            } else if (isBasic) {
                if (formattedVersion > richVbCompilerVersion) {
                    richVbCompilerName = "Visual Basic";
                    richVbCompilerVersion = formattedVersion;
                    richVbCompilerOptions = richOptions;
                }
            }
        }
    }

    if (richLinkerName) {
        linkerName = richLinkerName;
        linkerVersion = richLinkerVersion;
        linkerOptions = richLinkerOptions;
    }

    if (richVbCompilerName) {
        vbCompilerName = richVbCompilerName;
        vbCompilerVersion = richVbCompilerVersion;
        vbCompilerOptions = richVbCompilerOptions;
    } else if (richCppCompilerName) {
        cppCompilerName = richCppCompilerName;
        cppCompilerVersion = richCppCompilerVersion;
        cppCompilerOptions = richCppCompilerOptions;
    } else if (richMasmCompilerName) {
        masmCompilerName = richMasmCompilerName;
        masmCompilerVersion = richMasmCompilerVersion;
        masmCompilerOptions = richMasmCompilerOptions;
    }

    if (PE.isDeepScan()) {
        if (richCppCompilerName == String()) {
            if (PE.section.length >= 3) {
                var msVisualCrtPattern = "'Microsoft Visual C++ Runtime Library'"
                if (PE.isSignatureInSectionPresent(0, msVisualCrtPattern) ||
                    PE.isSignatureInSectionPresent(1, msVisualCrtPattern) ||
                    PE.isSignatureInSectionPresent(2, msVisualCrtPattern)) {
                    cppCompilerName = "Microsoft Visual C/C++";
                }
            }
        }
    }

    if (PE.isVerbose()) {
        if (richCppCompilerName == String()) {
            if (PE.isLibraryPresent("msvcrt.dll")) {
                var nMajorLinkerVersion = PE.getMajorLinkerVersion(),
                    nMinorLinkerVersion = PE.getMinorLinkerVersion();

                if (nMajorLinkerVersion >= 3 && nMajorLinkerVersion <= 14 && nMinorLinkerVersion < 40) {
                    cppCompilerName = "Microsoft Visual C/C++";
                }
            }
        }
    }

    if (PE.isVerbose()) {
        if (mfcLibraryName) {
            if (cppCompilerName == String()) {
                cppCompilerName = "Microsoft Visual C/C++";
                // TODO Version
            }
            if (linkerName == String()) {
                linkerName = "Microsoft Linker";
                // TODO Version
            }
        }

        if (cppCompilerName || richVbCompilerName || masmCompilerName) {
            if (linkerName == String()) {
                var nMajorLinkerVersion = PE.getMajorLinkerVersion(),
                    nMinorLinkerVersion = PE.getMinorLinkerVersion();

                if (nMajorLinkerVersion >= 3 && nMajorLinkerVersion <= 14 && nMinorLinkerVersion < 40) {
                    linkerName = "Microsoft Linker";
                }
            }
        }
    }

    if (linkerName) {
        if (linkerVersion == String()) {
            var nMajorLinkerVersion = PE.getMajorLinkerVersion(),
                nMinorLinkerVersion = PE.getMinorLinkerVersion();

            if (nMajorLinkerVersion >= 3 && nMajorLinkerVersion <= 14 && nMinorLinkerVersion < 40) {
                linkerVersion = PE.getCompilerVersion();
            }
        }
    }

    if (cppCompilerName && linkerName) {
        var linkerMajorVersion = linkerVersion.match(/\d+\.\d+/gm);

        if (linkerMajorVersion) {
            toolName = "Microsoft Visual Studio";

            var vsVersionMap = {
                "6.00": "6.0",
                "7.00": "2002",
                "7.10": "2003",
                "8.00": "2005",
                "9.00": "2008",
                "10.00": "2010",
                "11.00": "2012",
                "12.00": "2013",
                "14.00": "2015",
                "14.10": "2017, 15.0-15.2",
                "14.11": "2017, 15.3",
                "14.12": "2017, 15.5",
                "14.13": "2017, 15.6",
                "14.14": "2017, 15.7",
                "14.15": "2017, 15.8",
                "14.16": "2017, 15.9",
                "14.20": "2019, 16.0",
                "14.21": "2019, 16.1",
                "14.22": "2019, 16.2",
                "14.23": "2019, 16.3",
                "14.24": "2019, 16.4",
                "14.25": "2019, 16.5",
                "14.26": "2019, 16.6",
                "14.27": "2019, 16.7-16.8",
                "14.28": "2019, 16.9-16.10",
                "14.29": "2019, 16.11",
                "14.30": "2022, 17.0",
                "14.31": "2022, 17.1",
                "14.32": "2022, 17.2",
                "14.33": "2022, 17.3",
                "14.34": "2022, 17.4",
                "14.35": "2022, 17.5",
                "14.36": "2022, 17.6",
                "14.37": "2022, 17.7",
                "14.38": "2022, 17.8",
                "14.39": "2022, 17.9.1",
                "14.40": "2022, 17.10",
                "14.41": "2022, 17.11",
                "14.42": "2022, 17.12",
                "14.43": "2022, 17.13",
                "14.44": "2022, 17.14",
                "14.50": "2026, 18.0-18.3",
                "14.51": "2026, 18.4"
            };

            toolVersion = vsVersionMap[linkerMajorVersion] || "";
        }
    }

    if (masmCompilerVersion == "6.14.8444" && linkerVersion == "5.12.8078") {
        toolName = "MASM32";
        toolVersion = "8-11";
    }

    if (vbCompilerName) {
        _setLang("VB" + (vbCompilerName.indexOf(".NET") !== -1 ? ".NET" : ""));
        _setResult("compiler", vbCompilerName, vbCompilerVersion, vbCompilerOptions);
    } else if (cppCompilerName) {

        if (!_isResultPresent("compiler", "Rust")) { // check is Rust detected

            if (cppCompilerOptions.indexOf("C++") !== -1 || cppCompilerOptions.indexOf("CPP") !== -1) {
                _setLang("C++");
            } else if (cppCompilerOptions == "C" || cppCompilerOptions.indexOf("/C") !== -1 || cppCompilerOptions.indexOf("_C") !== -1) {
                _setLang("C");
            } else {
                _setLang("C/C++");
            }

        }

        // if not detected
        if (!_isResultPresent("compiler", cppCompilerName)) _setResult("compiler", cppCompilerName, cppCompilerVersion, cppCompilerOptions);
    } else if (masmCompilerName) {
        _setLang("ASMx" + (PE.is64() ? "64" : "86"));
        _setResult("compiler", masmCompilerName, masmCompilerVersion, masmCompilerOptions);
    }


    if (dotNetLibraryName) {

        if (PE.isNetObjectPresent("FSharp.Core")) _setLang("F#");
        if (!_isLangDetected()) _setLang("MSIL/C#");

        _setResult("library", dotNetLibraryName, dotNetLibraryVersion, dotNetLibraryOptions);
    }

    if (mfcLibraryName) {
        _setResult("library", mfcLibraryName, mfcLibraryVersion, mfcLibraryOptions);
    }

    if (linkerName && _getNumberOfResults("linker") < 1) {
        _setResult("linker", linkerName, linkerVersion, linkerOptions);
    }

    if (toolName && toolVersion) {
        _setResult("tool", toolName, toolVersion, toolOptions);
    }
}

function getVbOptions() {
    var result = String();

    // Check if sections exist before accessing section[0]
    if (PE.getNumberOfSections() === 0) {
        return result;
    }
    var firstSection = PE.section[0];

    var vbSignatureOffset = PE.findDword(firstSection.FileOffset, firstSection.FileSize, 0x21354256);

    if (vbSignatureOffset === -1) {
        vbSignatureOffset = PE.findDword(firstSection.FileOffset, firstSection.FileSize, 0x21364256);
    }

    if (vbSignatureOffset !== -1) {
        var virtualAddress = PE.readDword(vbSignatureOffset + 0x30),
            fileOffset = PE.VAToOffset(virtualAddress);

        if (fileOffset !== -1) {
            result = (PE.readDword(fileOffset + 0x20) === 0) ? "P-Code" : "Native";
        }
    }

    return result;
}
