如何获取 IEnumMoniker.Next 以在以管理员身份运行时返回名字对象?



这段代码在实用程序中运行良好多年。我们最近更新了程序以强制执行 UAC,但我们发现此代码仅在不以管理员身份运行时有效;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 在提升的进程中运行时不返回绰号,但在不以管理员身份运行时返回列表有任何想法?

我用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支持:

不幸的是,在这个领域没有任何改变的杠杆。

最新更新