• XSS.stack #1 – первый литературный журнал от юзеров форума

Определение версии Windows ++

SenctumSempra

RAM
Пользователь
Регистрация
05.10.2020
Сообщения
117
Реакции
26
Есть задача определить версию windows
Есть Функция GetVersion GetVersionEx, они не работают на 10-ках
Так же есть Функции IsWindows8OrGreater() в <VersionHelpers.h>

C++:
#include <VersionHelpers.h>

    if (!IsWindows8OrGreater())
    {
       MessageBox(NULL, "You need at least Windows 8", "Version Not Supported", MB_OK);
    }

Код с MSDN без внесений изменений
Может есть либа, которую нужно закоментить еще?
Снимок.PNG
 
Пожалуйста, обратите внимание, что пользователь заблокирован
На сколько я помню, RtlGetVersion из ntdll.dll на всех системах возвращает реальную версию.
 
На сколько я помню, RtlGetVersion из ntdll.dll на всех системах возвращает реальную версию.
А он разве не дает еще и версию билда самой Windows?
Мне просто достаточно было бы получить внутренний номер версии и чтобы моя программа не запускалась в версии ниже 6.2
т.е Win 7 отсечь и все что ниже
 
Вы можете использовать GetVerstion и GetVersionEx. Но по умолчанию они возваращют win8 на любой win8+. Но если вы укажите в манифесте, что знаете что существуют версии выше восьмой(конекретно в манифесте пропишите их GUID), то эти функции будут работать правильно. Подробнее здесь docs dot microsoft dot com/en-us/windows/win32/sysinfo/targeting-your-application-at-windows-8-1 Так же эту часть манифеста можно взять из приложения на С#, если не ошибаюсь там он создается автоматически. Тоесть вам нужно в манифест добавить тэг <compatibility> и GUID остальных версий

P.s Насчет функций из versionhelpers, я не уверен, что они работают корректно, если в манифесте не прописан <compatibility>, но здесь могу ошибаться
 
Вы можете использовать GetVerstion и GetVersionEx. Но по умолчанию они возваращют win8 на любой win8+. Но если вы укажите в манифесте, что знаете что существуют версии выше восьмой(конекретно в манифесте пропишите их GUID), то эти функции будут работать правильно. Подробнее здесь docs dot microsoft dot com/en-us/windows/win32/sysinfo/targeting-your-application-at-windows-8-1 Так же эту часть манифеста можно взять из приложения на С#, если не ошибаюсь там он создается автоматически. Тоесть вам нужно в манифест добавить тэг <compatibility> и GUID остальных версий

P.s Насчет функций из versionhelpers, я не уверен, что они работают корректно, если в манифесте не прописан <compatibility>, но здесь могу ошибаться
Спасибо, почитаю
 
Сейчас перечитал свое сообщение, наверное, мнгоим будет непонятно. Поэтому пошаговая инструкция(может кому пригодится)
1)Берем код и создаем файл с расширением .manifest (something.manifest)
Код:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
    <assemblyIdentity
        type="win32"
        name="Contoso.ExampleApplication.ExampleBinary"
        version="1.2.3.4"
        processorArchitecture="x86"
    />
    <description>Contoso Example Application</description>
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
            <!-- Windows 10 and Windows 11 -->
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
            <!-- Windows 8.1 -->
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
            <!-- Windows 8 -->
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
            <!-- Windows 7 -->
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
            <!-- Windows Vista -->
            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
        </application>
    </compatibility>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
                <!--
                  UAC settings:
                  - app should run at same integrity level as calling process
                  - app does not need to manipulate windows belonging to
                    higher-integrity-level processes
                  -->
                <requestedExecutionLevel
                    level="asInvoker"
                    uiAccess="false"
                />   
            </requestedPrivileges>
        </security>
    </trustInfo>
</assembly>

2)Добавляем его (как существующий) в свой проект

3)Собираем проект

Вот как я и говорил, если этого не сделать, то versionhelpers выдают нам не правильный результат....
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Можете попробовать через реестр threads/44535/, ключ доступен на чтение в том числе для процессов в сэндбоксе.

1643979471900.png
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Манифесты дело хорошее, и как бы рекомендовано самим негрософтом, но 1)много возни с правильным манифестом; 2)не особо подходит для малварей.

Так-то есть три варианта.
1. RtlGetVersion. - действует так, как GetVersionEx, те же структуры, но корректно работает на вин 8.1 и десятке.
2. Парсить KUSER_SHARED_DATA , по смещению 07FFE0000h
; printf("Version: %d.%d\n", *(ULONG*)(sharedUserData + 0x26c),*(ULONG*)(sharedUserData + 0x270));
3. парсить РЕВ, собственно RtlGetVersion именно оттуда берёт инфу.

Кстати, 11 винда все также возвращает везде 10.0, там надо смотреть по номеру билда (больше 22k)
 
alternatively, would it be less suspicious to check the psver?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Так-то есть три варианта
Из WMI и реестра еще можно взять.
 
Тебе нужно слинковать с Version.lib.
#pragma comment(lib, "Version.lib")
Можешь попробовать этот код если тебе нужен номер билда винды:
C++:
#include <iostream>
#include <windows.h>
#include <versionhelpers.h>
#pragma comment(lib, "Version.lib")

typedef struct
{
    char szBuildName[260];
    uint16_t MajorVersion;            // 6 for Windows Seven
    uint16_t MinorVersion;            // 1 for Windows Seven
    uint16_t BuildVersion;            // ex. 18362
    uint16_t PostBuildVersion;        // ex. 112
    uint16_t MarketVersion;            // ex. 1903
} BASE_OS_VERSION_INFO;

bool
GetSystemVersion(BASE_OS_VERSION_INFO* pVersion)
{
    WCHAR szPath[260] = {};
    BYTE StringInfo[1024] = {};

    if (IsWindows7OrGreater())
    {
        pVersion->MajorVersion = 6;
        pVersion->MinorVersion = 1;
    }
    else
    {
        return false;
    }

    if (IsWindows8OrGreater())
    {
        pVersion->MajorVersion = 6;
        pVersion->MinorVersion = 2;
    }

    // it's not just working before 8.1, because assholes in Microsoft can't
    // make basic function for check Windows version
    if (IsWindows8Point1OrGreater())
    {
        pVersion->MajorVersion = 6;
        pVersion->MinorVersion = 3;
    }

    if (IsWindows10OrGreater())
    {
        pVersion->MajorVersion = 10;
        pVersion->MinorVersion = 0;
    }

    // get system directory for check dll version
    if (GetSystemDirectoryW(szPath, sizeof(szPath)))
    {
        // use more updated library from system directory
        wcscat_s(szPath, L"\\ntoskrnl.exe");

        VS_FIXEDFILEINFO * pvi;
        DWORD sz = sizeof(VS_FIXEDFILEINFO);

        // get Windows version from ntdll library
        if (GetFileVersionInfoW(szPath, 0, sizeof(StringInfo), StringInfo))
        {
            if (VerQueryValueW(&StringInfo[0], L"\\", (LPVOID*)&pvi, (unsigned int*)&sz))
            {
                pVersion->MajorVersion = HIWORD(pvi->dwProductVersionMS);
                pVersion->MinorVersion = LOWORD(pvi->dwProductVersionMS);
                pVersion->BuildVersion = HIWORD(pvi->dwProductVersionLS);
                pVersion->PostBuildVersion = LOWORD(pvi->dwProductVersionLS);

                switch (pVersion->BuildVersion)
                {
                case 7600: pVersion->MarketVersion = 'S0'; break;
                case 7601: pVersion->MarketVersion = 'S1'; break;
                case 9200: pVersion->MarketVersion = 'S0'; break;
                case 9600: pVersion->MarketVersion = 'S1'; break;
                case 10240: pVersion->MarketVersion = 1507; break;
                case 10586: pVersion->MarketVersion = 1511; break;
                case 14393: pVersion->MarketVersion = 1607; break;
                case 15063: pVersion->MarketVersion = 1703; break;
                case 16299: pVersion->MarketVersion = 1709; break;
                case 17134: pVersion->MarketVersion = 1803; break;
                case 17763: pVersion->MarketVersion = 1809; break;
                case 18362: pVersion->MarketVersion = 1903; break;
                default: pVersion->MarketVersion = pVersion->BuildVersion; break;
                }           
            }
        }
    }

    LPCSTR WindowsVer = nullptr;
    switch (pVersion->MajorVersion)
    {
    case 10:
        WindowsVer = "10";
        break;
    case 6:
        if (pVersion->MinorVersion == 1)
        {
            WindowsVer = "7";
            break;
        }
        if (pVersion->MinorVersion == 2)
        {
            WindowsVer = "8";
            break;
        }
        if (pVersion->MinorVersion == 3)
        {
            WindowsVer = "8.1";
            break;
        }
    default:
        break;
    }

    bool isServicePacked = pVersion->MarketVersion == 'S1' || pVersion->MarketVersion == 'S0';

    if (!isServicePacked)
    {
        snprintf(
            pVersion->szBuildName,
            sizeof(pVersion->szBuildName),
            "Microsoft Windows %s %i (%s %i.%i)",
            WindowsVer,
            pVersion->MarketVersion,
            pVersion->BuildVersion == pVersion->MarketVersion ? "Insider build" : "Build",
            pVersion->BuildVersion,
            pVersion->PostBuildVersion
        );
    }
    else
    {
        snprintf(
            pVersion->szBuildName,
            sizeof(pVersion->szBuildName),
            "Microsoft Windows %s %s(%s %i.%i)",
            WindowsVer,
            pVersion->MarketVersion == 'S1' ? "Service Pack 1 " : "",
            pVersion->BuildVersion == pVersion->MarketVersion ? "Insider build" : "Build",
            pVersion->BuildVersion,
            pVersion->PostBuildVersion
        );
    }

    return true;
}


int main()
{
    BASE_OS_VERSION_INFO baseInfo = {};

    if (GetSystemVersion(&baseInfo))
    {
        printf("Windows OS information: \n%s", baseInfo.szBuildName);
    }

    printf("\nPress any key to close console window");

    _getwch();
    ExitProcess(0);

    return 0;
}
 
Тебе нужно слинковать с Version.lib.
#pragma comment(lib, "Version.lib")
Можешь попробовать этот код если тебе нужен номер билда винды:
C++:
#include <iostream>
#include <windows.h>
#include <versionhelpers.h>
#pragma comment(lib, "Version.lib")

typedef struct
{
    char szBuildName[260];
    uint16_t MajorVersion;            // 6 for Windows Seven
    uint16_t MinorVersion;            // 1 for Windows Seven
    uint16_t BuildVersion;            // ex. 18362
    uint16_t PostBuildVersion;        // ex. 112
    uint16_t MarketVersion;            // ex. 1903
} BASE_OS_VERSION_INFO;

bool
GetSystemVersion(BASE_OS_VERSION_INFO* pVersion)
{
    WCHAR szPath[260] = {};
    BYTE StringInfo[1024] = {};

    if (IsWindows7OrGreater())
    {
        pVersion->MajorVersion = 6;
        pVersion->MinorVersion = 1;
    }
    else
    {
        return false;
    }

    if (IsWindows8OrGreater())
    {
        pVersion->MajorVersion = 6;
        pVersion->MinorVersion = 2;
    }

    // it's not just working before 8.1, because assholes in Microsoft can't
    // make basic function for check Windows version
    if (IsWindows8Point1OrGreater())
    {
        pVersion->MajorVersion = 6;
        pVersion->MinorVersion = 3;
    }

    if (IsWindows10OrGreater())
    {
        pVersion->MajorVersion = 10;
        pVersion->MinorVersion = 0;
    }

    // get system directory for check dll version
    if (GetSystemDirectoryW(szPath, sizeof(szPath)))
    {
        // use more updated library from system directory
        wcscat_s(szPath, L"\\ntoskrnl.exe");

        VS_FIXEDFILEINFO * pvi;
        DWORD sz = sizeof(VS_FIXEDFILEINFO);

        // get Windows version from ntdll library
        if (GetFileVersionInfoW(szPath, 0, sizeof(StringInfo), StringInfo))
        {
            if (VerQueryValueW(&StringInfo[0], L"\\", (LPVOID*)&pvi, (unsigned int*)&sz))
            {
                pVersion->MajorVersion = HIWORD(pvi->dwProductVersionMS);
                pVersion->MinorVersion = LOWORD(pvi->dwProductVersionMS);
                pVersion->BuildVersion = HIWORD(pvi->dwProductVersionLS);
                pVersion->PostBuildVersion = LOWORD(pvi->dwProductVersionLS);

                switch (pVersion->BuildVersion)
                {
                case 7600: pVersion->MarketVersion = 'S0'; break;
                case 7601: pVersion->MarketVersion = 'S1'; break;
                case 9200: pVersion->MarketVersion = 'S0'; break;
                case 9600: pVersion->MarketVersion = 'S1'; break;
                case 10240: pVersion->MarketVersion = 1507; break;
                case 10586: pVersion->MarketVersion = 1511; break;
                case 14393: pVersion->MarketVersion = 1607; break;
                case 15063: pVersion->MarketVersion = 1703; break;
                case 16299: pVersion->MarketVersion = 1709; break;
                case 17134: pVersion->MarketVersion = 1803; break;
                case 17763: pVersion->MarketVersion = 1809; break;
                case 18362: pVersion->MarketVersion = 1903; break;
                default: pVersion->MarketVersion = pVersion->BuildVersion; break;
                }          
            }
        }
    }

    LPCSTR WindowsVer = nullptr;
    switch (pVersion->MajorVersion)
    {
    case 10:
        WindowsVer = "10";
        break;
    case 6:
        if (pVersion->MinorVersion == 1)
        {
            WindowsVer = "7";
            break;
        }
        if (pVersion->MinorVersion == 2)
        {
            WindowsVer = "8";
            break;
        }
        if (pVersion->MinorVersion == 3)
        {
            WindowsVer = "8.1";
            break;
        }
    default:
        break;
    }

    bool isServicePacked = pVersion->MarketVersion == 'S1' || pVersion->MarketVersion == 'S0';

    if (!isServicePacked)
    {
        snprintf(
            pVersion->szBuildName,
            sizeof(pVersion->szBuildName),
            "Microsoft Windows %s %i (%s %i.%i)",
            WindowsVer,
            pVersion->MarketVersion,
            pVersion->BuildVersion == pVersion->MarketVersion ? "Insider build" : "Build",
            pVersion->BuildVersion,
            pVersion->PostBuildVersion
        );
    }
    else
    {
        snprintf(
            pVersion->szBuildName,
            sizeof(pVersion->szBuildName),
            "Microsoft Windows %s %s(%s %i.%i)",
            WindowsVer,
            pVersion->MarketVersion == 'S1' ? "Service Pack 1 " : "",
            pVersion->BuildVersion == pVersion->MarketVersion ? "Insider build" : "Build",
            pVersion->BuildVersion,
            pVersion->PostBuildVersion
        );
    }

    return true;
}


int main()
{
    BASE_OS_VERSION_INFO baseInfo = {};

    if (GetSystemVersion(&baseInfo))
    {
        printf("Windows OS information: \n%s", baseInfo.szBuildName);
    }

    printf("\nPress any key to close console window");

    _getwch();
    ExitProcess(0);

    return 0;
}
Твой код полностью рабочий, благодарю
И спасибо всем за помощь так же!
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх