Windows 从桌面应用程序访问OSK(屏幕键盘)句柄,无需管理员权限

Windows 从桌面应用程序访问OSK(屏幕键盘)句柄,无需管理员权限,windows,winapi,privileges,kiosk-mode,Windows,Winapi,Privileges,Kiosk Mode,我有一个桌面delphi应用程序,在Windows7和Windows8上运行时没有管理员权限。此应用程序需要将(SendInput)鼠标事件(单击并移动)发送到另一个正在运行的应用程序。该应用程序的工作原理类似于远程wifi笔的驱动程序,可控制桌面上的鼠标。当焦点在OSK(屏幕键盘上)上时,按下左键时鼠标移动不工作,OSK窗口不移动,所有其他应用程序在接收这些移动事件时移动。我能搞定OSK。 当我以管理员权限(UAC)运行我的应用程序时,一切正常,当应用程序发送move envets时OSK移动

我有一个桌面delphi应用程序,在Windows7和Windows8上运行时没有管理员权限。此应用程序需要将(SendInput)鼠标事件(单击并移动)发送到另一个正在运行的应用程序。该应用程序的工作原理类似于远程wifi笔的驱动程序,可控制桌面上的鼠标。当焦点在OSK(屏幕键盘上)上时,按下左键时鼠标移动不工作,OSK窗口不移动,所有其他应用程序在接收这些移动事件时移动。我能搞定OSK。 当我以管理员权限(UAC)运行我的应用程序时,一切正常,当应用程序发送move envets时OSK移动。 我认为这个问题与UAC有关。我找到了这样一种绕过UAC的方法,但在某些环境下这不是一个好主意。 有没有办法绕过UAC而不用地下通道?或者我如何强制OSK对我发送给他的所有鼠标事件做出响应



以下是嵌入在Osk.exe中的清单片段:

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level="asInvoker" uiAccess="true"/>
    </requestedPrivileges>
  </security>
</trustInfo>

请注意它要求的
级别,因为Invoker不要求UAC标高,只有RequiredAdministrator要求。换句话说,它以启动程序拥有的任何权限运行。可以看出,启动Osk.exe时不会得到同意提示

这里重要的是
uiAccess
。设置为true时,程序绕过UIPI。用户界面特权隔离是UAC的一对鲜为人知的孪生兄弟,它通过禁止另一个进程将键盘敲击和鼠标点击插入升级应用程序所拥有的窗口来防止粉碎攻击。这样一个过程仍然在高完整性模式下运行,这就是为什么你不能亲自进入Osk,但没有使UAC提升的应用程序变得危险的特权

这并不罕见,大多数使用UI自动化或提供可访问性功能的程序都需要能够做到这一点。与Osk.exe一样,它需要能够在任何应用程序中插入按键。很明显,你也想做什么

获取uiAccess不需要用户像UAC elevation那样同意提示。操作系统必须“信任”你。在“UI自动化应用程序的UIAccess”一节中有详细介绍。我在这里总结一下:

  • 在应用程序清单中设置uiAccess=“true”
  • 您的可执行文件必须具有有效的数字证书,即您从Verisign等供应商处购买的那种证书
  • 您的可执行文件必须存储在c:\program files或c:\windows的子目录中,该目录的写入访问被拒绝

    • 以下是嵌入在Osk.exe中的清单的剪贴:

      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
          <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="true"/>
          </requestedPrivileges>
        </security>
      </trustInfo>
      
      
      
      请注意它要求的
      级别,因为Invoker不要求UAC标高,只有RequiredAdministrator要求。换句话说,它以启动程序拥有的任何权限运行。可以看出,启动Osk.exe时不会得到同意提示

      这里重要的是
      uiAccess
      。设置为true时,程序绕过UIPI。用户界面特权隔离是UAC的一对鲜为人知的孪生兄弟,它通过禁止另一个进程将键盘敲击和鼠标点击插入升级应用程序所拥有的窗口来防止粉碎攻击。这样一个过程仍然在高完整性模式下运行,这就是为什么你不能亲自进入Osk,但没有使UAC提升的应用程序变得危险的特权

      这并不罕见,大多数使用UI自动化或提供可访问性功能的程序都需要能够做到这一点。与Osk.exe一样,它需要能够在任何应用程序中插入按键。很明显,你也想做什么

      获取uiAccess不需要用户像UAC elevation那样同意提示。操作系统必须“信任”你。在“UI自动化应用程序的UIAccess”一节中有详细介绍。我在这里总结一下:

      • 在应用程序清单中设置uiAccess=“true”
      • 您的可执行文件必须具有有效的数字证书,即您从Verisign等供应商处购买的那种证书
      • 您的可执行文件必须存储在c:\program files或c:\windows的子目录中,该目录的写入访问被拒绝

      请注意,
      SendInput()
      并没有将任何东西插入OSK,反之亦然
      SendInput()
      将输入消息发布到硬件键盘/鼠标执行的相同队列中。当操作系统处理输入消息时,当前关注的任何应用程序都会收到这些消息。所以OSK(或任何其他应用程序)不知道或不关心鼠标点击是假的还是真的。Raymond Chen有一个……,所以你的解释虽然有用且信息丰富,但并不能真正解释为什么OSK只在Leonardo的应用程序运行时才对来自
      SendInput()
      的鼠标输入做出反应。无论应用程序是否在提升状态下运行,它都应该始终做出反应。UIPI避免了跨不同完整性级别将消息直接发送到窗口的攻击。
      SendInput()
      的情况并非如此。如果有什么区别的话,当Leo的应用程序没有提升运行时,它很可能以与OSK相同的完整性级别运行,并且无论如何也不会被UIPI阻止,除非OSK正在提升运行。这让我怀疑,在Leo的情况下,OSK是否真的在提升运行。如果是的话,这也许可以解释为什么他不能从非提升过程中控制它,如果这真的是UAC/UIPI问题的话。好吧,Hans Passant的uiAccess=true的解决方案可以在没有提升提示的情况下工作。在一个名为uac.exe的简单应用程序中,hans的程序可以运行,我可以移动osk窗口。但在最后一个应用程序上,我做了同样的处理,弹出一个带有“无效文件名”的警报,所有的都是一样的,唯一的区别是失败应用程序的名称,有9个字符的长度,PenDriver.exe。清单中的限制是8吗?但是请注意,
      SendInput()