2

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

目前这个机制是这样工作的:

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

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

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

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

为了解决这个问题,我找到了这个UIAccess标志(请参阅此处,并向下滚动到它显示“ UIAccess for UI automation applications ”的位置。)

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

在此处输入图像描述

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

它运行得很好:

在此处输入图像描述

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

我在那里错过了什么?

4

1 回答 1

4

您所描述的内容包含在 Win32 API 文档中:

PostMessage 功能

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

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

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

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

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

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

只有在更高权限的应用程序通过消息调用明确允许时,较低权限的模式才能将消息发送到更高权限的应用程序ChangeWindowMessageFilter()。此外,较低权限的应用程序只能读取HWND由较高权限的应用程序拥有的。

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

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

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

较低权限的进程不能:

– 执行更高进程权限的窗口句柄验证。
SendMessagePostMessage更高权限的应用程序窗口。这些应用程序编程接口 (API) 返回成功,但默默地丢弃窗口消息
– 使用线程挂钩附加到更高权限的进程。
– 使用日志挂钩来监控更高权限的进程。
– 执行动态链接库 (DLL) – 注入更高权限的进程。

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

– 桌面窗口,实际上拥有屏幕表面
– 桌面堆只读共享内存
– 全局原子表
– 剪贴板

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

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

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

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

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

于 2016-10-19T18:59:35.780 回答