如何在Windows内核驱动程序中将文本SID转换为SID结构?

时间:2015-04-23 18:42:41

标签: driver wdk windows-kernel

我的内核驱动程序应该从注册表中读取文本格式的SID,并将其转换为SID结构以供后续使用。

内核驱动程序是否有ConvertStringSidtoSid()类似物?

我知道我可以解析文本并手工构建它,但它看起来像通常的任务。 搜索无法找到任何内容。

1 个答案:

答案 0 :(得分:1)

没有人回答我的问题而且我写了一些代码并希望分享。

它适用于我的所有用例。可能对某人有用:

BOOLEAN
IprParseSubAuthorities(
    _In_ PCWCHAR buffer,
    _Out_ PISID pSid
)
{
    ULONG authority = 0;
    UCHAR count = 0;
    for (USHORT i = 0;; i++)
    {
        if ((buffer[i] >= L'0') && (buffer[i] <= L'9'))
        {
            authority = authority * 10 + (buffer[i] - L'0');
            continue;
        }
        else if (buffer[i] == L'-')
        {
            pSid->SubAuthority[count] = authority;
            authority = 0;

            if (++count >= pSid->SubAuthorityCount)
            {
                return FALSE;
            }
            continue;
        }
        else if (buffer[i] == 0)
        {
            break;
        }
        return FALSE;
    }
    pSid->SubAuthority[count] = authority;
    return TRUE;
}

UCHAR IprGetSubAuthorityCount(
    _In_ PCWCHAR buffer
)
{
    UCHAR count = 1; // buffer should contains at least one authority
    for (UCHAR i = 0;; i++)
    {
        if (buffer[i] == L'-')
        {
            count++;
        }
        else if (buffer[i] == 0)
        {
            break;
        }
    }
    return count;
}

BOOLEAN
IprConvertUnicodeSidtoSid(
    _In_ PUNICODE_STRING UnicodeSid,
    _Out_ PISID* ppSid
)
{
    PCWCHAR PREFIX = L"S-1-5-";
    const USHORT PREFIX_LEN = (USHORT)wcslen(PREFIX);
    SIZE_T result = RtlCompareMemory(PREFIX, UnicodeSid->Buffer, PREFIX_LEN);
    if (result != PREFIX_LEN)
    {
        return FALSE;
    }
    UCHAR subAuthorityCount =
        IprGetSubAuthorityCount(UnicodeSid->Buffer + PREFIX_LEN);

    PISID pSid = ExAllocatePool(PagedPool, sizeof(SID) + sizeof(ULONG) * (subAuthorityCount - 1));

    pSid->Revision = 1;
    pSid->IdentifierAuthority.Value[0] = 0;
    pSid->IdentifierAuthority.Value[1] = 0;
    pSid->IdentifierAuthority.Value[2] = 0;
    pSid->IdentifierAuthority.Value[3] = 0;
    pSid->IdentifierAuthority.Value[4] = 0;
    pSid->IdentifierAuthority.Value[5] = 5;
    pSid->SubAuthorityCount = subAuthorityCount;

    if (!IprParseSubAuthorities(UnicodeSid->Buffer + PREFIX_LEN, pSid))
    {
        ExFreePool(pSid);
        return FALSE;
    }

    if (!RtlValidSid(pSid))
    {
        ExFreePool(pSid);
        return FALSE;
    }

    *ppSid = pSid;
    return TRUE;
}