Как я могу получить IEnumMoniker.Next для возврата моникеров при работе от имени администратора? - PullRequest
0 голосов
/ 02 апреля 2019

Этот код отлично работал в течение многих лет внутри служебной программы. Недавно мы обновили программу для обеспечения контроля учетных записей, но обнаружили, что этот код работает, только когда НЕ работает от имени администратора; код внутри цикла while никогда не выполняется при запуске от имени администратора, но тот же код возвращает список имен моникеров при выполнении без выравнивания.

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace ROTExplorer
{
    class Program
    {
    [DllImport("ole32.dll")]
    static extern int GetRunningObjectTable(uint reserved, out IRunningObjectTable rot);

    [DllImport("Ole32.Dll")]
    static extern int CreateBindCtx(int reserved, out IBindCtx bindCtx);

    static void Main(string[] args)
    {
        FindEntryInROT();
        Console.WriteLine("Press any key to continue.");
        Console.ReadKey();
    }

    private static string FindEntryInROT()
    {
        IRunningObjectTable rot = null;
        IBindCtx bindCtx = null;
        IEnumMoniker enumMoniker = null;
        IMoniker[] monikers = new IMoniker[1];
        string displayName = null;
        try
        {
            GetRunningObjectTable(0, out rot);
            CreateBindCtx(0, out bindCtx);
            rot.EnumRunning(out enumMoniker);
            IntPtr fetched = IntPtr.Zero;
            while (enumMoniker.Next(1, monikers, fetched) == 0)
            {
                string tempName;
                monikers[0].GetDisplayName(bindCtx, null, out tempName);
                Marshal.ReleaseComObject(monikers[0]);
                monikers[0] = null;
                try
                {
                    Console.WriteLine(tempName);
                }
                catch
                {
                    Console.WriteLine("Bad string");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Failure while examining ROT: " + ex.Message);
        }
        finally
        {
            ReleaseCOMObject(monikers[0]);
            ReleaseCOMObject(enumMoniker);
            ReleaseCOMObject(bindCtx);
            ReleaseCOMObject(rot);
        }
        Console.WriteLine(displayName);
        return displayName;
    }

    private static void ReleaseCOMObject(object comObject)
    {
        if (comObject != null)
        {
            Marshal.ReleaseComObject(comObject);
            comObject = null;
        }
    }

}

Я пробовал это на 2 машинах. Может кто-то еще, пожалуйста, попробуйте это и подтвердите, что этот код возвращает список имен только тогда, когда НЕ работает от имени администратора.

Есть ли у кого-нибудь мысли о том, почему IEnumMoniker не возвращает моникеров при запуске в процессе с повышенными правами, но возвращает список, если он не запущен от имени администратора?

1 Ответ

0 голосов
/ 25 апреля 2019

Я открыл тикет с Microsoft.Он обострился, и я наконец получил ответ: он работает как задумано.Вот соответствующий разговор:

Служба поддержки Microsoft:

Служба SCM / RPCSS - это то место, где находится таблица работающих объектов.Когда таблица перечисляется, служба выполняет несколько проверок.Одна из этих проверок специально предназначена для сопоставления уровня повышения клиентского токена с уровнем повышения записи токена.Если он не совпадает, то запись не будет возвращена.Поведение, которое вы видите, является умышленным.

Я:

Можете ли вы выслать мне ссылку, где это задокументировано?Наличие «повышенных» привилегий должно дать пользователю доступ к большему количеству объектов, а не к меньшим.То, что вы описываете, похоже на простое вход в систему от имени другого пользователя.

Служба поддержки Microsoft:

Непосредственно не документировано.
В некоторых отношенияхВаше последнее утверждение верно.Администратор имеет два токена безопасности: один для нормальной работы и один для повышенных.Они никогда не используются одновременно.https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works Когда администратор входит в систему, для пользователя создаются два отдельных токена доступа: стандартный токен доступа пользователя и токен доступа администратора.Стандартный токен доступа пользователя содержит ту же информацию, специфичную для пользователя, что и токен доступа администратора, но административные привилегии Windows и SID удалены.Я полагаю, что причина всего этого связана с безопасностью, но я не могу объяснить это очень хорошо.

Я:

Маркер администратора имеет доступ к стандартупользовательские файлы;почему COM-объекты пользователя обрабатываются иначе, чем файловые объекты пользователя?

Поддержка Microsoft:

Потому что это дизайнерское решение, принятое группой продуктов.У меня нет дополнительной информации о том, почему они так сделали.

Я:

Это действительно звучит для меня как ошибка или неправильный дизайн.Есть ли способ поместить это на радар группы продуктов?

Поддержка Microsoft:

К сожалению, нет никаких рычагов для получения каких-либо изменений в этой области.

...