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

Получаем версию Windows через WMI

Jeffs

(L1) cache
Забанен
Регистрация
28.12.2018
Сообщения
611
Реакции
358
Пожалуйста, обратите внимание, что пользователь заблокирован
Тупо перелопатил пример с msdn, мб кому пригодится:

Скрытый контент для зарегистрированных пользователей.

C:
HRESULT GetWinVer(LPSTR winVer)
{
    HRESULT hres;

    hres = CoInitializeEx(0, COINIT_MULTITHREADED);

    if (FAILED(hres))
    {
        return hres;
    }

    hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL);

    if (FAILED(hres))
    {
        CoUninitialize();
        return hres;
    }

    IWbemLocator* pLoc = NULL;

    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);

    if (FAILED(hres))
    {
        CoUninitialize();
        return hres;
    }

    IWbemServices* pSvc = NULL;

    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);

    if (FAILED(hres))
    {
        pLoc->Release();
        CoUninitialize();
        return hres;
    }

    hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return hres;
    }

    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_OperatingSystem"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return hres;
    }

    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
            &pclsObj, &uReturn);

        if (uReturn == 0)
        {
            break;
        }

        VARIANT vtProp;

        hr = pclsObj->Get(L"Version", 0, &vtProp, 0, 0);
        lstrcatA(winVer, _com_util::ConvertBSTRToString(vtProp.bstrVal));
        VariantClear(&vtProp);

        pclsObj->Release();
    }

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();

    return hres;
}


Использование:

C:
int main(int argc, char** argv)
{
    static char winVer[100];
    
    if (FAILED(GetWinVer(winVer)))
    {
        return 1;
    }
    
    wcout << "WinVer: " << winVer << endl;
    return 0;
}
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Преобразовываем в человекопонятный вид:
Код:
func GetWinVer(ver1, ver2, build string) string {
    switch ver1 {
    case "6":
        if ver2 == "0" {
            if build == "6000" {
                return "Win Vista"
            } else if build == "6001" {
                return "Win Vista SP1"
            } else if build == "6002" {
                return "Win Vista SP2"
            } else if build == "6003" {
                return "Win Vista SP2 KB4489887"
            }
        }
        if ver2 == "1" {
            if build == "7600" {
                return "Win 7"
            } else if build == "7601" {
                return "Win 7 SP1"
            }
        }
        if ver2 == "2" {
            if build == "9200" {
                return "Win 8"
            }
        } else if ver2 == "3" {
            if build == "9600" {
                return "Win 8.1"
            }
        }
    case "10":
        if ver2 == "0" {
            if build == "10240" {
                return "Win 10.1507"
            } else if build == "10586" {
                return "Win 10.1511"
            } else if build == "14393" {
                return "Win 10.1607"
            } else if build == "15063" {
                return "Win 10.1703"
            } else if build == "16299" {
                return "Win 10.1709"
            } else if build == "17134" {
                return "Win 10.1803"
            } else if build == "17763" {
                return "Win 10.1809"
            } else if build == "18362" {
                return "Win 10.1903"
            } else if build == "18363" {
                return "Win 10.1909"
            }
        }
    }

    return "Win Unknwn"
}
У меня бэк на golang, можете переписать под любой другой язык.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Это конечно круто, но зачем все эти телодвижения, если минор и мажор можно вытащить из PEB?
Билд оттуда не вытащить. У одной только win 10 под десяток версий
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Билд оттуда не вытащить. У одной только win 10 под десяток версий
На х64 по смещению 0x120 в пебе лежит номер билда. Это то, что юзал я. На х32 тоже есть.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
На х64 по смещению 0x120 в пебе лежит номер билда. Это то, что юзал я. На х32 тоже есть.
Не знал, если честно. Надо бы переписать всё это дело
 
Кстати, ещё суть в том, что если ты будешь делать запросы в вми - на это могут поставить детект, поведенческие анализаторы это запалят моментально. А вот при работе с пебом все ок.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
C:
BOOL GetWinVer(LPSTR winVerStr)
{
    OSVERSIONINFOEXA winVer;
    DWORD majorVer, minorVer, winBuild;
    memset(&winVer, 0, sizeof(winVer));
    winVer.dwOSVersionInfoSize = sizeof(winVer);

    if (!GetVersionExA((LPOSVERSIONINFOA)&winVer))
    {
        return FALSE;
    }

    majorVer = winVer.dwMajorVersion;
    minorVer = winVer.dwMinorVersion;
    winBuild = winVer.dwBuildNumber;

    sprintf(winVerStr, "majorVer: %d\nminorVer: %d\nwinBuild: %d", majorVer, minorVer, winBuild);

    return TRUE;
}

int main(int argc, char** argv)
{
    static char winVer[100];

    if (GetWinVer(winVer))
    {
        printf("%s", winVer);
    }

    return 0;
}
На выходе получаю:
majorVer: 6
minorVer: 2
winBuild: 9200
Хотя на вм стоит Windows 10 1607. Что не так с кодом?
 
C:
BOOL GetWinVer(LPSTR winVerStr)
{
    OSVERSIONINFOEXA winVer;
    DWORD majorVer, minorVer, winBuild;
    memset(&winVer, 0, sizeof(winVer));
    winVer.dwOSVersionInfoSize = sizeof(winVer);

    if (!GetVersionExA((LPOSVERSIONINFOA)&winVer))
    {
        return FALSE;
    }

    majorVer = winVer.dwMajorVersion;
    minorVer = winVer.dwMinorVersion;
    winBuild = winVer.dwBuildNumber;

    sprintf(winVerStr, "majorVer: %d\nminorVer: %d\nwinBuild: %d", majorVer, minorVer, winBuild);

    return TRUE;
}

int main(int argc, char** argv)
{
    static char winVer[100];

    if (GetWinVer(winVer))
    {
        printf("%s", winVer);
    }

    return 0;
}
На выходе получаю:
majorVer: 6
minorVer: 2
winBuild: 9200
Хотя на вм стоит Windows 10 1607. Что не так с кодом?
Подробнее читай мсдн. Эта функция не актуальна.
 
[GetVersionEx may be altered or unavailable for releases after Windows 8.1. Instead, use the Version Helper functions]

With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version. The value returned by the GetVersionEx function now depends on how the application is manifested.


Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2). Once an application is manifested for a given operating system version, GetVersionEx will always return the version that the application is manifested for in future releases. To manifest your applications for Windows 8.1 or Windows 10, refer to Targeting your application for Windows.
 
C:
    PBYTE pPEB = (PBYTE)__readfsdword(0x30);
    PDWORD pdwMinor = (PDWORD)(pPEB + 0x00A8);
    PDWORD pdwMajor = (PDWORD)(pPEB + 0x00A4);
    PDWORD pdwBuild = (PDWORD)(pPEB + 0x00AC);

    WCHAR wszOS[MAX_PATH] = { 0 };
    
    wsprintfW(wszOS, L"OS Minor: %d, Major: %d, Build: %d", *pdwMinor, *pdwMajor, *pdwBuild);

    MessageBoxW(0, wszOS, 0, MB_OK);
Держи. Накалякал рабочий пример под x86.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
C:
    PBYTE pPEB = (PBYTE)__readfsdword(0x30);
    PDWORD pdwMinor = (PDWORD)(pPEB + 0x00A8);
    PDWORD pdwMajor = (PDWORD)(pPEB + 0x00A4);
    PDWORD pdwBuild = (PDWORD)(pPEB + 0x00AC);

    WCHAR wszOS[MAX_PATH] = { 0 };
  
    wsprintfW(wszOS, L"OS Minor: %d, Major: %d, Build: %d", *pdwMinor, *pdwMajor, *pdwBuild);

    MessageBoxW(0, wszOS, 0, MB_OK);
Держи. Накалякал рабочий пример под x86.
Под win7 что-то не совсем корректно билд определяет:
CxvdJ2r.png

На win10 1607 всё нормально отрабатывает
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Спасибо за пример с WMI, конечно через РЕВ лучше, но разный код нужен. + хороший вариант, как работать с СОМ на Си. Т.к. через WMI много чего еще сделать можно.
Под win7 что-то не совсем корректно билд определяет:
Почему? Семерка это же и есть вин 6.1, или ты о билде?

Еще есть такой вариант, работает корректно в отличие от винапи, которая deprecated
C:
    RTL_OSVERSIONINFOW info = { sizeof(info) };
    RtlGetVersion(&info);
    KdPrint(("Windows Version: %d.%d.%d\n", info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber));
 
Пожалуйста, обратите внимание, что пользователь заблокирован
И так, в общем разобрался получением версии ОС через PEB, вот код:
C:
#include <Windows.h>
#include <stdio.h>

#include "ntdll.h" //структура PEB

int main()
{
    PEB* pPEB = (PEB*)__readfsdword(0x30);
    PDWORD pdwMajor = (PDWORD)pPEB->OSMajorVersion;
    PDWORD pdwMinor = (PDWORD)pPEB->OSMinorVersion;
    PDWORD pdwBuild = (PDWORD)pPEB->OSBuildNumber;

    WCHAR wszOS[MAX_PATH] = { 0 };

    wsprintfW(wszOS, L"%d.%d.%d", pdwMajor, pdwMinor, pdwBuild);

    MessageBoxW(0, wszOS, 0, MB_OK);

}

Отрабатывает коррекетно на всех системах.
Видимо на семёрке OSBuildNumber немного по другому адресу сидит.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Спасибо за пример с WMI, конечно через РЕВ лучше, но разный код нужен. + хороший вариант, как работать с СОМ на Си. Т.к. через WMI много чего еще сделать можно.

Почему? Семерка это же и есть вин 6.1, или ты о билде?

Еще есть такой вариант, работает корректно в отличие от винапи, которая deprecated
C:
    RTL_OSVERSIONINFOW info = { sizeof(info) };
    RtlGetVersion(&info);
    KdPrint(("Windows Version: %d.%d.%d\n", info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber));
Да как оказалось, можно и GetVersion заставить определять версию ОС корректно. В манифесте нужно указать, что поддеживаем десятку.
 


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