Win32 - 作为普通用户进程启动最高可用子进程

2024-03-29

假设您的 Windows 用户帐户位于 Admin 组中,启用了 UAC,并且您正在以普通用户权限运行某些程序 A。 A从不要求提升,也从未得到提升。现在假设 A 想要启动程序 B,该程序的清单中具有 HighestAvailable。

  • 如果 A 调用 CreateProcess(B),则会失败并出现错误 740(“需要提升”)

  • 如果 A 调用 ShellExecuteEx(B),Windows 将显示一个 UAC 框,要求提升运行 B。用户可以说是,在这种情况下 B 将运行提升,或者说否,在这种情况下启动将失败。

我的问题是:有没有办法实现第三种选择,即我们只需启动 B 而无需提升?

原则上这似乎是可能的,因为“highestAvailable”意味着 Bprefers以海拔运行,但完全能够在普通用户模式下运行。但我想不出任何方法来实现它。我已经尝试了使用令牌和 CreateProcessAsUser() 的各种方法,但这一切似乎都归结为:“highestAvailable”似乎不可改变地指的是用户帐户固有的潜在权限,而不是任何显式表达的实际权限。构建的令牌。

我希望实际上有某种方法可以使用 CreateProcessAsUser() 来执行此操作,并且我只是缺少正确构建令牌的技巧。

更新-已解决:下面的 __COMPAT_LAYER=RunAsInvoker 解决方案效果很好。不过,有一点需要注意。这会强制子进程无条件地“作为调用者”运行:即使被调用的 exe 在其清单中指定了“requireAdministrator”,它也适用。我认为当 exe 指定“requireAdministrator”时,最初的“需要提升”错误通常更可取。我希望标有“highestAvailable”的程序的 RunAsInvoker 行为的全部原因是,此类程序明确表示“我可以在任一模式下正常运行” - 因此,当不方便使用管理模式时,让我们继续以普通用户模式运行。但“requireAdministrator”是另一回事:此类程序会说“如果没有提升的权限,我将无法正常运行”。对于此类程序来说,预先失败似乎比强制它们以未提升的速度运行更好,这可能会使它们遇到未正确编程来处理的特权/访问错误。因此,我认为这里的完整通用解决方案需要检查应用程序清单,并且仅在清单显示“highestAvailable”时才应用 RunAsInvoker 强制。更完整的解决方案是使用其他地方讨论的技术之一,为调用者提供在出现“requireAdministrator”程序时调用 UAC 的选项,并为用户提供启动它的机会。我可以想象一个 CreateProcessEx() 覆盖了几个新标志,用于“将进程权限视为最高可用权限”和“如果需要提升,则调用 UAC”。 (下面描述的另一种方法,挂钩 NTDLL!RtlQueryElevationFlags() 来告诉 CreateProcess() UAC 不可用,对于 requireAdministrator 程序具有完全相同的警告。)

(这可能表明 Windows shell 甚至没有提供执行此操作的方法...直接从 shell 启动 B 将为您提供 UAC 框,让您可以使用管理员权限启动或根本不启动。如果有不管怎样,UAC 框可能会提供第三个按钮,无需特权即可启动。但话又说回来,这可能只是用户体验决定,因为第三个选项对平民来说太令人困惑了。)

(请注意,StackOverflow 和 Microsoft 开发支持网站上有很多帖子询问看似非常相似的场景,但遗憾的是,该场景并不适用于此处。该场景是指您有一个正在运行提升的父程序,并且它想要启动一个非提升的子进程。典型的例子是一个安装程序,按照安装程序倾向于做的方式运行提升,它想要在正常用户级别启动刚刚安装的程序,就在它退出之前。有很多关于如何做到这一点,我已经基于其中一些技术进行了尝试,但这确实是一个不同的场景,并且解决方案在我的情况下不起作用。最大的区别是他们尝试启动的子程序在这种情况下isn't标记为 HighestAvailable - 该子程序只是一个正常程序,在正常情况下无需任何 UAC 参与即可启动。还有另一个区别,即在这些场景中,父级已经在提升的级别运行,而在我的场景中,父级正在以普通用户级别运行;这会稍微改变一些事情,因为在其他场景中,父进程可以访问令牌上的一些特权操作,但我无法使用这些特权操作,因为 A 本身并未提升。但据我所知,那些特权令牌操作无论如何都无济于事;事实上,孩子拥有最高的可用标志,这是我的场景的关键元素。)


Set the __COMPAT_LAYER环境变量为RunAsInvoker https://devblogs.microsoft.com/oldnewthing/20161117-00/?p=94735在你的过程中。我不认为这在任何地方都有正式记录,但它一直可以追溯到 Vista。

您还可以通过将其设置为永久的AppCompatFlags\Layers注册表中的密钥。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Win32 - 作为普通用户进程启动最高可用子进程 的相关文章

  • SetForegroundWindow 不适用于最小化进程[重复]

    这个问题在这里已经有答案了 找不到关于这个主题的任何好的答案 所以也许有人可以帮助我 我正在制作一个小型个人程序 我想将某个应用程序带到前台 它已经可以工作了 但是有一个小问题 当进程最小化时 我的代码将无法工作 该进程不会像未最小化时那样
  • 为什么没有定义 PCTSTR 而定义了 LPCTSTR?

    我被指派更新用 MSVC 6 编写的旧代码 我得到了 PCTSTR 的未知定义 但即使我包含了 tchar h 它也没有定义 根据我以前的经验 我知道有 LPTSTR 但没有 PCTSTR 我 grep C Program Files Mi
  • 在哪里可以找到 Python 的 win32api 模块? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要下载 Python 2 7 的它 但似乎找不到它 还有一个新选项 通过 pip 获取 有一个包p
  • 如何编写通用 C 函数来调用 Win32 函数?

    为了允许从脚本语言 用 C 编写 访问 Win32 API 我想编写一个如下所示的函数 void Call LPCSTR DllName LPCSTR FunctionName LPSTR ReturnValue USHORT Argume
  • 运行时更改进程名称 (C++)

    是否可以在 win32 中运行时更改进程的名称 任务管理器中 进程 下出现的名称 我希望该程序能够更改自己的名称 而不是其他程序的名称 帮助将不胜感激 最好是 C 为了消除任何关于病毒的想法 不 这不是病毒 是的 我知道我在做什么 这是为了
  • 如何指示窗口过程中处理消息时出现的错误?

    我目前正在编写一个库来处理来自原始输入 API 的信息 并且我正在使用级联函数 这导致了几个非常小 非常可读且非常集中的函数 但是 它让我震惊 我不明白如何properly表明 Windows 出现故障 我有这个功能 OnInput Han
  • 如何在 Windows 8 上注册自定义 Win+V 热键?

    可以在 Windows 8 之前的 Windows 版本上注册 Win V 热键 使用此组合的示例应用程序是PureText http www stevemiller net puretext 在 Windows 8 Release Pre
  • Windows EventLog:它的操作速度有多快?

    我有一个服务应用程序 它通过 TCP 处理客户端请求并将任何事件写入 Windows EventLog 由于该应用程序预计会在短时间内为许多客户端和每个客户端的大量请求提供服务 假设每秒 1 到 50 个请求 因此我很想知道密集程度 CPU
  • 如何使用VerQueryValue?

    我有一个 exe 需要从特定 dll 检索版本信息 例如 FileDescription 我的代码已经调用了 GetFileVersionInfoSize 和 GetFileVersionInfo 但我不知道如何应用 VerQueryVal
  • 如何检测媒体是否已插入可移动驱动器/读卡器

    我有一个读卡器 未插入记忆棒 当我插入计算机时 它在 我的电脑 中显示一个空驱动器 是否有可能知道驱动器是否有媒体 抱歉我不知道如何称呼它 或没有 我找到的建议MSalters to use IOCTL STORAGE CHECK VERI
  • HWND 创建时间

    我是这个社区的新手 在使用我的自动化脚本 1 时遇到一个问题 我想获取 HWND 的创建时间 我在从 FindWindowEx 检索到的数组中有一组 HWND 我想在数组中找到最后根据系统时间创建的 HWND 我对窗口钩子没有足够的了解 但
  • 如果我被冒充,为什么 Win32 API 函数 CredEnumerate() 会返回 ERROR_NOT_FOUND?

    我编写了一些示例代码 当我在普通用户帐户的上下文中从 Windows 命令提示符调用这些代码时 会使用 CredEnumerate 转储所有用户保存的凭据 但是 我真的希望能够从 SYSTEM 用户上下文执行此操作 因此我从 SYSTEM
  • Win32:将窗口置于顶部

    我有一个 Windows 程序 其中有两个 2 窗口 hwnd main interface hwnd2 toplevel window no parent created by hwnd 当我双击 hwnd 时 我需要弹出 hwnd2 并
  • :: 右侧的非法标记

    我有以下模板声明 template
  • 如何获取当前所选键盘布局的显示名称

    我需要以语言栏显示输入语言的方式向用户显示输入语言列表 例如 目前我有 class Program static void Main string args var langs InputLanguage InstalledInputLan
  • Windows 8 SDK 中的 DirectX

    Summary 是否应该从针对 Windows 8 的应用程序中删除 directX 包含文件 Details 我是 Windows 开发新手 我正在尝试使用 Visual Studio 2012 如果可能 在 Windows 8 上编译
  • 为什么 SetCursorPos 将光标位置重置到显示屏的左侧?

    SetCursorPos https learn microsoft com en us windows win32 api winuser nf winuser setcursorpos将光标移动到指定的屏幕坐标 然而 它似乎有一个错误
  • 为什么 FindWindow 找到了 EnumChildWindows 找不到的窗口?

    我正在寻找一个类名称为 CLIPBRDWNDCLASS 的窗口 它可以在办公应用程序和其他应用程序中找到 如果我使用 FindWindow 或 FindWindowEx 我找到第一个具有此类的 HWND 但我想要all具有该类的窗口 因此我
  • 从剪贴板获取文本后将一个字符串插入另一个字符串所需的建议

    简介及相关信息 我有一个edit control只需要接受带符号的十进制数 类似于 12 35 我决定通过以下方式实现这一点subclassing The WM CHAR处理程序似乎运行良好 我需要处理其他几条消息以完全保护用户免于输入无效
  • 在 C# 中根据鼠标点击获取活动窗口名称

    我正在尝试使应用程序获取用户单击的窗口的鼠标单击位置和标题 名称 我目前使用的是 LowLevelMouseProc 它提供了良好的结果 但每当我单击 Google chrome 时 它 都会使应用程序崩溃 这是代码 using Syste

随机推荐