跨进程PostMessage、UIPI限制和UIAccess=”true”

c00*_*0fd 5 c++ windows winapi sendmessage uipi

出于安全原因,我的应用程序的 UI 模块以high 强制完整性级别运行。除了一件事之外,其中的所有内容都运行良好。为了与旧版本兼容,我需要能够让用户向 UI 模块发出命令行调用。

目前该机制的工作原理如下:

  1. Windows 资源管理器中的快捷方式调用我的模块,如下所示:

    path-to-module\module.exe -op="a, s, r"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 当进程解析此命令行时,它会使用FindWindow通过其唯一的类名来module.exe定位正在运行的 UI 模块副本(或自身的另一个副本) 。然后,它使用PostMessage API 向其发送注册消息

  3. 然后,正在运行的 UI 模块(具有high完整性级别)在收到消息时会相应地对其进行处理。

问题在于,由于UI模块的运行副本具有high完整性级别,因此它无法接收来自较低完整性级别的消息,或者当Windows资源管理器运行该模块的副本以解析快捷方式命令时,它无法接收来自较低完整性级别的消息,这使得它以medium完整性级别运行等级。

为了解决这个问题,我找到了这个UIAccess标志(请参阅此处,然后向下滚动到“ UIAccess for UI Automation applications ”。)

所以我的假设是,如果我设置此标志并对我的 UI 模块进行代码签名:

在此输入图像描述

它将能够绕过我上面描述的 UIPI 限制。

它运行得很好:

在此输入图像描述

但我看到的是,PostMessage当我从以完整性级别运行的模块调用它时,我上面描述的算法中的 API 仍然失败,并显示 ERROR_ACCESS_DENIED medium

我在那里错过了什么?

Rem*_*eau 6

Win32 API 文档中涵盖了您所描述的内容:

\n\n

留言功能

\n\n
\n

如果函数失败,返回值为零。要获取扩展错误信息,请调用 GetLastError。ERROR_NOT_ENOUGH_QUOTA当达到限制时GetLastError 返回。

\n\n

当消息被 UIPI 阻止时,使用 GetLastError 检索到的最后一个错误将设置为 5(访问被拒绝)。

\n
\n\n

其中 UIPI 是用户界面权限隔离

\n\n
\n

什么是用户界面权限隔离 (UIPI)

\n\n

这也称为 UI 特权级别隔离 (UIPI)。

\n\n

作为 Vista 中安全启动的一部分,具有 UI 的应用程序将以三个不同的权限级别运行。应用程序窗口可以与相同或较低级别的其他窗口交互,但不能与更高级别/权限的应用程序交互。

\n\n

仅当较高权限应用程序通过消息调用明确允许时,较低权限模式才可以向较高权限应用程序发送消息ChangeWindowMessageFilter()。此外,较低特权的应用程序只能读取HWND较高特权应用程序所拥有的数据。

\n\n

Internet Explorer 是一个以最低权限级别运行的示例进程。

\n\n

参考链接:
\n http://msdn2.microsoft.com/en-us/library/ms632675.aspx
\n http://msdn.microsoft.com/library/default.asp?url=/library/en-us /dnlong/html/AccProtVista.asp

\n\n

UIPI 通过阻止以下行为来防止较低权限进程访问较高权限进程。

\n\n

较低权限的进程不能:

\n\n

\xe2\x80\x93 执行更高进程权限的窗口句柄验证。
\n \xe2\x80\x93SendMessagePostMessage更高权限的应用程序窗口。这些应用程序编程接口 (API) 返回成功,但默默地删除窗口消息
\n \xe2\x80\x93 使用线程挂钩附加到更高权限的进程。
\n \xe2\x80\x93 使用日志挂钩来监视更高权限的进程。
\n \xe2\x80\x93 执行动态链接库(DLL)\xe2\x80\x93注入到更高权限的进程。

\n\n

启用 UIPI 后,以下共享 USER 资源仍然在不同权限级别的进程之间共享。

\n\n

\xe2\x80\x93 桌面窗口,实际拥有屏幕表面
\n \xe2\x80\x93 桌面堆只读共享内存
\n \xe2\x80\x93 全局原子表
\n \xe2\x80\x93 剪贴板

\n
\n\n

正如文档所述,较高权限的应用程序需要使用ChangeWindowMessageFilter()来允许来自较低权限应用程序的特定窗口消息:

\n\n
\n

在用户界面权限隔离 (UIPI) 消息过滤器中添加或删除消息。

\n
\n\n

在 Windows 7 及更高版本上,请改用ChangeWindowMessageFilterEx()

\n\n
\n

修改指定窗口的用户界面权限隔离 (UIPI) 消息过滤器。

\n
\n\n

因此,在您的情况下,在您的较高特权进程调用RegisterWindowMessage()以获取已注册的消息 ID 后,它需要将该 ID 传递给ChangeWindowMessageFilter/Ex()以便从较低特权进程接收该消息。

\n