在 UNICODE_STRING 中搜索字符

Search for character in UNICODE_STRING

有一个UNICODE_STRING,我想检查其中是否有一个定义的字符(最好是:末尾的$)。

我们正在使用 OpenPasswordFilter 并想检查提交的帐户是用户还是计算机。如果是计算机,定义为末尾的'$',则不检查。

NTSTATUS PsamPasswordNotificationRoutine(
  PUNICODE_STRING UserName,
  ULONG RelativeId,
  PUNICODE_STRING NewPassword
)
{...}

来自 https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nc-ntsecapi-psam_password_notification_routine

在 c# 中我会使用类似的东西:

char lastchar = UserName[UserName.Length - 1];
if (lastchar <> '$') {
....

这样的事情可能会奏效: 请记住 PUNICODE_STRING 的长度是字节数而不是 "characters"

的字节数
if (UserName->Buffer)
{
    std::wstring w = std::wstring(reinterpret_cast<wchar_t*>(UserName->Buffer), UserName->Length / sizeof(wchar_t));

    if(w[w.size()-1] != L'$')
    {
        ...
    }
}

UNICODE_STRING::Buffer 是指向 wchar_t[] 数组的指针。您可以直接查看Buffer的内容,例如:

enum eAccountType {atUnknown, atUser, atComputer};

eAccountType GetAccountType(const wchar_t *UserName, int Length)
{
    return ((UserName) && (Length > 0))
        ? ((UserName[Length-1] == L'$') ? atComputer : atUser)
        : atUnknown;
}

eAccountType GetAccountType(const UNICODE_STRING &UserName)
{
    // UNICODE_STRING::Length is expressed in bytes, not in characters...
    return GetAccountType(UserName.Buffer, UserName.Length / sizeof(wchar_t));
}

NTSTATUS PsamPasswordNotificationRoutine(
    PUNICODE_STRING UserName,
    ULONG RelativeId,
    PUNICODE_STRING NewPassword
)
{
    ...
    if ((UserName) && (GetAccountType(*UserName) == atUser))
    {
        ...
    }
    ...
}