# No Need COM WMI

I was messing around with Windows. I was poking Windows with a big stick.

I ended up falling down a rabbit hole ([Google Project Zero](https://www.exploit-db.com/exploits/42213), [UnknownCheats](https://www.unknowncheats.me/forum/anti-cheat-bypass/407062-wmi-hook-kernel.html)) and managed to do WMI stuff from C without using the Windows COM.

These APIs are extremely undocumented and were kind of a pain in the butt cheeks. There is more stuff you can do. However, for the time being here is my proof-of-concept for getting SYSTEM\_INFORMATION in C.

```ps1
PS C:\Users\User\Desktop> ([WMIClass]"root\wmi:MS_SystemInformation").GetText(
>>     [System.Management.TextFormat]::Mof
>> )
[WMI, dynamic: ToInstance, provider("WMIProv"), Guid("{98A2B9D7-94DD-496a-847E-67A5557A59F2}"), Locale(1033)]
class MS_SystemInformation
{
        [key, read] string InstanceName;
        [read] boolean Active;
        [read, WMIDataID(1)] string BaseBoardManufacturer;
        [read, WMIDataID(2)] string BaseBoardProduct;
        [read, WMIDataID(3)] string BaseBoardVersion;
        [read, WMIDataID(4)] string BIOSReleaseDate;
        [read, WMIDataID(5)] string BIOSVendor;
        [read, WMIDataID(6)] string BIOSVersion;
        [read, WMIDataID(7)] string SystemFamily;
        [read, WMIDataID(8)] string SystemManufacturer;
        [read, WMIDataID(9)] string SystemProductName;
        [read, WMIDataID(10)] string SystemSKU;
        [read, WMIDataID(11)] string SystemVersion;
        [read, WMIDataID(12)] uint8 BiosMajorRelease;
        [read, WMIDataID(13)] uint8 BiosMinorRelease;
        [read, WMIDataID(14)] uint8 ECFirmwareMajorRelease;
        [read, WMIDataID(15)] uint8 ECFirmwareMinorRelease;
};

```

```ps1
PS C:\Users\User\Desktop> Get-CimInstance -ClassName MS_SystemInformation -Namespace root\wmi


Active                 : True
BaseBoardManufacturer  : ASUSTeK COMPUTER INC.
BaseBoardProduct       : Z790 GAMING WIFI7
BaseBoardVersion       : Rev 1.xx
BiosMajorRelease       : 16
BiosMinorRelease       : 61
BIOSReleaseDate        : 06/25/2024
BIOSVendor             : American Megatrends Inc.
BIOSVersion            : 1661
ECFirmwareMajorRelease : 255
ECFirmwareMinorRelease : 255
InstanceName           : ROOT\mssmbios\0000_0
SystemFamily           : NZXT
SystemManufacturer     : NZXT, Inc.
SystemProductName      : NZXT
SystemSKU              : NZXT BLD
SystemVersion          : NZXT
PSComputerName         :
```

```cpp
#include <Windows.h>

#pragma comment(lib, "advapi32.lib")

typedef NTSTATUS(WINAPI* WMIOPENBLOCK)(GUID, ULONG, PHANDLE);
typedef NTSTATUS(WINAPI* WMICLOSEBLOCK)(HANDLE);
typedef NTSTATUS(WINAPI* WMIQUERYALLDATA)(HANDLE, PULONG, PBYTE);

typedef struct _WNODE_HEADER
{
    ULONG BufferSize;
    ULONG ProviderId;
    union
    {
        ULONG64 HistoricalContext;
        struct
        {
            ULONG Version;
            ULONG Linkage;
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME;

    union
    {
        ULONG CountLost;
        HANDLE KernelHandle;
        LARGE_INTEGER TimeStamp;
    } DUMMYUNIONNAME2;
    GUID Guid;
    ULONG ClientContext;
    ULONG Flags;
} WNODE_HEADER, * PWNODE_HEADER;

 typedef struct _OFFSETINSTANCEDATAANDLENGTH {
    ULONG OffsetInstanceData;
    ULONG LengthInstanceData; 
} OFFSETINSTANCEDATAANDLENGTH, *POFFSETINSTANCEDATAANDLENGTH;

typedef struct tagWNODE_ALL_DATA
{
    struct _WNODE_HEADER WnodeHeader;
    ULONG DataBlockOffset;
    ULONG InstanceCount;
    ULONG OffsetInstanceNameOffsets;
    union
    {
        ULONG FixedInstanceSize;
        OFFSETINSTANCEDATAANDLENGTH OffsetInstanceDataAndLength[];
    } DUMMYUNIONNAME;

}WNODE_ALL_DATA, *PWNODE_ALL_DATA;

PWCHAR WmiGetStringFromDataBlockW(PBYTE* Pointer, PBYTE End)
{
    PBYTE LocalPointer = *Pointer;
    USHORT Length = 0;
    PWCHAR String = NULL;

    if (LocalPointer + sizeof(USHORT) > End)
        goto EXIT_ROUTINE;

    Length = *(PUSHORT)LocalPointer;
    LocalPointer += sizeof(USHORT);

    if (Length == 0 || LocalPointer + Length > End) 
    {
        *Pointer = LocalPointer;
        goto EXIT_ROUTINE;
    }

    String = (PWCHAR)LocalPointer;
    LocalPointer += Length;

    if ((ULONGLONG)LocalPointer & 1)
        ++LocalPointer;

    *Pointer = LocalPointer;

EXIT_ROUTINE:

    return (String != NULL ? String : (PWCHAR)L"");
}

INT main(VOID)
{
    HMODULE Module = NULL;
    BOOL bFlag = FALSE;
    DWORD dwError = ERROR_SUCCESS;

    WMIOPENBLOCK WmiOpenBlock = NULL;
    WMICLOSEBLOCK WmiCloseBlock = NULL;
    WMIQUERYALLDATA WmiQueryAllDataW = NULL;

    HANDLE WmiHandle = NULL;
    ULONG  DataSize = 0;

    GUID SystemInformation = { 0x98A2B9D7, 0x94DD, 0x496a, { 0x84, 0x7E, 0x67, 0xA5, 0x55, 0x7a, 0x59, 0xF2 } };

    PWNODE_ALL_DATA WmiData = NULL;
    PBYTE RawData = NULL;
    PBYTE Base = NULL;
    PBYTE BaseNodePointer = NULL;
    PBYTE BaseNodeEnd = NULL;

    ULONG InstanceOffset = 0;
    ULONG InstanceLength = 0;

    UCHAR BiosMajorRelease = 0;
    UCHAR BiosMinorRelease = 0;
    UCHAR ECFirmwareMajorRelease = 0;
    UCHAR ECFirmwareMinorRelease = 0;

    PWCHAR SystemInformationArray[11] = { 0 };

    Module = LoadLibraryA("advapi32.dll");
    if (!Module)
        goto EXIT_ROUTINE;

    WmiOpenBlock = (WMIOPENBLOCK)GetProcAddress(Module, "WmiOpenBlock");
    WmiCloseBlock = (WMICLOSEBLOCK)GetProcAddress(Module, "WmiCloseBlock");
    WmiQueryAllDataW = (WMIQUERYALLDATA)GetProcAddress(Module, "WmiQueryAllDataW");

    if (!WmiOpenBlock || !WmiCloseBlock || !WmiQueryAllDataW)
        goto EXIT_ROUTINE;

    if (WmiOpenBlock(SystemInformation, GENERIC_READ, &WmiHandle) != ERROR_SUCCESS)
        goto EXIT_ROUTINE;

    WmiQueryAllDataW(WmiHandle, &DataSize, nullptr);
    if (DataSize == 0)
        goto EXIT_ROUTINE;

    RawData = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DataSize);
    if (!RawData)
        goto EXIT_ROUTINE;

    if (WmiQueryAllDataW(WmiHandle, &DataSize, RawData) != ERROR_SUCCESS)
        goto EXIT_ROUTINE;

    WmiData = (PWNODE_ALL_DATA)RawData;
    if (WmiData->InstanceCount == 0)
        goto EXIT_ROUTINE;

    InstanceOffset = WmiData->OffsetInstanceDataAndLength[0].OffsetInstanceData;
    InstanceLength = WmiData->OffsetInstanceDataAndLength[0].LengthInstanceData;

    if (InstanceOffset + InstanceLength > DataSize)
        goto EXIT_ROUTINE;

    Base = RawData + InstanceOffset;
    BaseNodePointer = Base;
    BaseNodeEnd = Base + InstanceLength;

    for (DWORD Ordinal = 0; Ordinal < 11; Ordinal++)
        SystemInformationArray[Ordinal] = (PWCHAR)WmiGetStringFromDataBlockW(&BaseNodePointer, BaseNodeEnd);

    if (BaseNodePointer + 4 <= BaseNodeEnd)
    {
        BiosMajorRelease = BaseNodePointer[0];
        BiosMinorRelease = BaseNodePointer[1];
        ECFirmwareMajorRelease = BaseNodePointer[2];
        ECFirmwareMinorRelease = BaseNodePointer[3];
    }

    bFlag = TRUE;

EXIT_ROUTINE:

    if (!bFlag)
        dwError = GetLastError();

    if (RawData)
        HeapFree(GetProcessHeap(), 0, RawData);

    if (WmiHandle)
        WmiCloseBlock(WmiHandle);

    return dwError;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://malwaresourcecode.com/home/my-projects/proof-of-concepts/no-need-com-wmi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
