New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support UI Automation within a Windows Defender Application Guard process #7600

Merged
merged 9 commits into from Oct 9, 2017

Conversation

Projects
None yet
4 participants
@michaelDCurran
Contributor

michaelDCurran commented Sep 13, 2017

Summary of the issue:

On Windows 10 Enterprise, it is now possible to run Microsoft Edge within Windows Defender application Guard (WDAG). WDAG is a stripped-back version of Windows running in a special virtual machine that can securely isolate a process from the rest of the system.
The only way that an asistive technology can talk to the isolated process is via UI Automation. Nothing else can cross the machine boundary.
WDAG perfectly forwards the UI Automation implementation from the isolated process, but changes the processID property on each UIA element to expose the local WDAG process ID rather than the process ID inside the VM. However, the following two problems exist:

  • currently WDAG does not change the nativeWindowHandle property and therefore that property exposes handle values from the isolated process which are completely invalid on the local machine.
  • The local window that hosts the entire WDAG content does not report itself as having a native UIA implementation.
    These problems together mean that NVDA pretty much stays silent when focus is within a WDAG process and therefore if a user decides to run Microsoft Edge in this fassion it is completely inaccessible.

Description of how this pull request fixes the issue:

  • UIA NVDAObjects should never use their UIAElement's nativeWindowHandle as the NVDAObject's windowHandle. Rather they should always use UIAHandler.handler.getNearestwindowHandle. This was mostly already true, though sometimes nativeWindowHandle was still taking preidence if it existed.
  • UIAHandler.handler.getNearestWindowhandle: this function used to just find the first non-NULL nativeWindowHandle on a UIAElement and its ancestors. However now it also checks to see if the UIAElement is a WDAG UIAElement and if so then uses the root windowHandle for the process (which is the local windowHandle on this machine). In other words, all UIA NVDAObjects representing UIAElements within WDAG will now have a valid local windowHandle which is simply the root of the WDAG process.
  • UIAHandler.handler.isUIAWindow: if the window is a 'RAIL_WINDOW' then it should always be classed as being a UIA window. 'RAIL_WINDOW' is the window class given to the local window that hosts WDAG content.

These changes make NVDA function with Microsoft Edge in WDAG exactly the same way it would if Edge was running locally. The only difference being a noticeable drop in responsiveness.

Testing performed:

On a windows 10 Enterprise machine:

  • Went to Turn Windows Features On or Off, and selected Windows Defender Application Guard and pressed okay and rebooted etc.
  • Launched Microsoft Edge.
  • Whent to Settings and more -> New Application Guard window
  • In the new Microsoft Edge process that appeared, went to https://www.nvaccess.org/
  • Read the page using browse mode, tab, quick navigation etc.

Known issues with pull request:

If the name of the WDAG process ever changes (it is currently hvsirdpclient), not only will the WDAG process be inaccessible, but most importantly NVDA and or other parts of the system may experience hans or crashes due to the use of a nativeWindowHandle from a remote machine that is not valid locally. I have suggested to Microsoft that this is a major risk. Note though that without this PR the risk still remains the same.

Change log entry:

New features:

  • Support for Microsoft Edge running within Windows Defender Application Guard

michaelDCurran added some commits Sep 1, 2017

Prototype support for WDAG (Windows Defender Application Guard)
changes:
* UIAHandler.getNearestWindowHandle: If this UIAElement's processID is for a local WDAG container process, jump up to its root (UIA className of "ApplicationFrameWindow") and use that element's windowHandle. Any windowHandle from UIAElements below this root are not valid on this machine. However before we check for the WDAG process, if the processID of the original element is 0, search up for the first valid one (Known WDAG bug)
* UIAHandler.IsNativeUIAElement: If the processID is 0 (such as with UIAElements currently in WDAG), treat this UIAElement as having a native UIA implementation
* UIA NVDAObject: don't get the processID of the UIAElement, instead fallback to getting it off its window. Currently a UIAElement in WDAG may have a processID of 0. This is a known bug. It should be the processID of the local container process.
* UIAHandler.isNativeUIAElement: if the processID is for the local wd…
…ag container process, then this element should be classed as being native.

* Ensure IUIAutomationElement.cachedNativeWindowHandle is never used when it is not local -- needs to be rethought a bit.
UIAHandler.isUIAWindow: mark RAIL_WINDOW as always being native UIA. …
…this allows screen hittesting, and allows us to remove some other code from UIAHandler.isNativeUIAElement.

@michaelDCurran michaelDCurran requested a review from feerrenrut Sep 13, 2017

@josephsl

This comment has been minimized.

Show comment
Hide comment
@josephsl

josephsl Sep 13, 2017

Collaborator
Collaborator

josephsl commented Sep 13, 2017

@josephsl

This comment has been minimized.

Show comment
Hide comment
@josephsl

josephsl Sep 13, 2017

Collaborator
Collaborator

josephsl commented Sep 13, 2017

@michaelDCurran

This comment has been minimized.

Show comment
Hide comment
@michaelDCurran

michaelDCurran Sep 13, 2017

Contributor
Contributor

michaelDCurran commented Sep 13, 2017

@feerrenrut

This comment has been minimized.

Show comment
Hide comment
@feerrenrut

feerrenrut Sep 13, 2017

Contributor

Is there some way that NVDA can query for the name of the WDAG process?

Contributor

feerrenrut commented Sep 13, 2017

Is there some way that NVDA can query for the name of the WDAG process?

@feerrenrut

No need for me to re-review the review actions, unless you think the changes require it.

Show outdated Hide outdated source/_UIAHandler.py Outdated
@michaelDCurran

This comment has been minimized.

Show comment
Hide comment
@michaelDCurran

michaelDCurran Sep 13, 2017

Contributor
Contributor

michaelDCurran commented Sep 13, 2017

michaelDCurran added a commit that referenced this pull request Sep 13, 2017

UIAHandler's getNearestWindowHandle: partial support for File Explore…
…r in WDAG by also looking for File Explorer's UIA class name.

@michaelDCurran michaelDCurran merged commit 05789d2 into master Oct 9, 2017

1 check passed

continuous-integration/appveyor/branch AppVeyor build succeeded
Details

@nvaccessAuto nvaccessAuto removed the incubating label Oct 9, 2017

@nvaccessAuto nvaccessAuto added this to the 2017.4 milestone Oct 9, 2017

@josephsl josephsl referenced this pull request Oct 15, 2017

Merged

Docs17.4 #7662

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment