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

时间:2016-10-19 05:35:50

标签: c++ windows winapi sendmessage uipi

出于安全原因,我的应用程序的UI模块使用high mandatory integrity level运行。除了一件事,它里面的一切都很棒。为了与旧版本兼容,我需要能够让用户向UI模块发出命令行调用。

目前这种机制是这样的:

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

    path-to-module\module.exe -op="a, s, r"
    
  2. module.exe进程解析此命令行时,它会使用FindWindow以其唯一的类名来查找UI模块(或其他自我副本)的运行副本。然后,它使用registered message API发送PostMessage

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

  4. 问题在于,因为UI模块的运行副本具有high完整性级别,所以它无法从较低的完整性级别接收消息,或者在Windows资源管理器运行时无法接收模块的副本解析一个快捷命令,使其以medium完整性级别运行。

    为了解决这个问题,我找到了这个UIAccess标记(see here,然后向下滚动到它所说的" UI自动化应用程序的UIAccess "。 )

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

    enter image description here

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

    运行得很好:

    enter image description here

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

    我错过了什么?

1 个答案:

答案 0 :(得分:4)

Win32 API文档中介绍了您所描述的内容:

PostMessage function

  

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

     

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

UIPI为User Interface Privilege Isolation的地方:

  

什么是用户界面权限隔离(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)返回成功但静默地删除窗口消息    - 使用线程挂钩附加到更高权限进程    - 使用Journal钩子监视更高权限的过程    - 执行动态链接库(DLL) - 注入更高权限的进程。

     

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

     

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

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

  

从用户界面权限隔离(UIPI)邮件过滤器添加或删除邮件。

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

  

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

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