カーネル ドライバーは、レジストリから SID をテキスト形式で読み取り、それを後で使用できるように SID 構造に変換する必要があります。
カーネル ドライバーのConvertStringSidtoSid()アナログはありますか?
テキストを解析して手動で作成できることはわかっていますが、それは通常のタスクのように見えます。検索しても何も見つかりません。
カーネル ドライバーは、レジストリから SID をテキスト形式で読み取り、それを後で使用できるように SID 構造に変換する必要があります。
カーネル ドライバーのConvertStringSidtoSid()アナログはありますか?
テキストを解析して手動で作成できることはわかっていますが、それは通常のタスクのように見えます。検索しても何も見つかりません。
誰も私の質問に答えません。コードを書いて共有したいと思います。
私のすべてのユースケースで機能しました。誰かに役立つかもしれません:
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;
}