#c# #uac #running-object-table
#c# #uac #запуск-object-table
Вопрос:
Этот код годами работал нормально внутри служебной программы. Недавно мы обновили программу для принудительного управления доступом, но мы обнаружили, что этот код работает только при запуске БЕЗ имени администратора; код внутри цикла 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. Реальный пример заключается в том, что в нынешнем виде административная утилита не может воспользоваться OLE для отправки выходных данных в электронную таблицу без запуска Excel от имени администратора.
2. Итак, вам удалось решить эту проблему?
3. не совсем (см. Ответ ниже) — либо отключите UAC, либо используйте OLE только между программами, запущенными с одинаковыми привилегиями (обе с повышенными или обе без повышенных)
4. Понял. Правильная регистрация в ROT с использованием ROTFLAGS_ALLOWANYCLIENT помогла мне решить аналогичную проблему, конечно, это не поможет, если вы не контролируете процедуру регистрации.
Ответ №1:
Я открыл заявку в Microsoft. Это было увеличено, и я, наконец, получил ответ: это работает так, как задумано. Вот соответствующий разговор:
Служба поддержки Microsoft:
Служба SCM / RPCSS — это место, где находится таблица запущенных объектов. Когда таблица перечисляется, служба выполняет несколько проверок. Одна из этих проверок специально предназначена для сопоставления уровня прав доступа токена клиента с уровнем прав доступа записи токена. Если это не соответствует, то запись не будет возвращена. Поведение, которое вы видите, разработано специально.
Я:
Можете ли вы прислать мне ссылку, где это задокументировано? Наличие «повышенных» привилегий должно предоставлять пользователю доступ к большему количеству объектов, а не к меньшему. То, что вы описываете, похоже, сродни простому входу в систему от имени другого пользователя.
Служба поддержки Microsoft:
Это не задокументировано напрямую.
В некотором смысле ваше последнее утверждение верно. Пользователь с правами администратора имеет два токена безопасности, один для обычной работы и один для повышенных. Они никогда не используются одновременно. https://learn.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works Когда администратор входит в систему, для пользователя создаются два отдельных токена доступа: стандартный токен доступа пользователя и токен доступа администратора. Стандартный токен доступа пользователя содержит ту же информацию о пользователе, что и токен доступа администратора, но административные привилегии Windows и SID удалены. Я полагаю, что причина всего этого связана с безопасностью, но я не могу это очень хорошо объяснить.
Я:
Токен администратора имеет доступ к файлам обычного пользователя; почему COM-объекты пользователя обрабатываются иначе, чем файловые объекты пользователя?
Служба поддержки Microsoft:
Потому что это дизайнерское решение, принятое группой продуктов. У меня нет дополнительной информации о том, почему именно они сделали это таким образом.
Я:
Для меня это действительно звучит как ошибка или ошибочный дизайн. Есть ли способ показать это группе продуктов?
Служба поддержки Microsoft:
К сожалению, нет рычагов для получения каких-либо изменений в этой области.