App-V 5: The Case of the RunVirtual Collision
I've discussed running native applications within virtual environments and the many ways we can bring applications like Internet Explorer into the bubble. One of the many reasons we would need to bring IE into the virtual environment is for web applications that use different versions of Java. When you virtualize different versions of Java, the shortcuts that are created will launch inside the bubble (and also through the /appvve switch.) For example, in the figure below, I have two specific Java packages deployed – each with its own Internet Explorer shortcut configured to run inside a separate Java bubble. I use the URL javatester.org to verify the version.
I can also view the java processes from the sysinternals utility Process Explorer running successfully launched from their own respective immutable package directory locations.
I can use another Sysinternals utility ListDLLS.exe to show that the App-V hook DLL has been injected into the Internet Explorer and Java processes.
You will also notice that if you configure RDS RunVirtual (where you use the AppV RunVirtual registry key to allow Internet Explorer to run inside a virtual package) to load Java into Internet Explorer, that you can see the Java application spawned by the IEXPLORE.EXE process inside of Process Explorer.
Differences from Dynamic Virtualization in SP2
You may notice in SP2 (as I believed I also mentioned in my last blog post) that when you launch Explorer and Internet Explorer, you will find that these also contain the injected AppVEntSubsystems32.dll due to the default dynamic virtualization configuration – however – just because you see EXPLORER.EXE and IEXPLORE.EXE hooked with LISTDLLS does not mean they will automatically behave the same way as if the application where configured for Run Virtual. App-V 5.0 SP2 introduced this feature as response to the historical desire for the virtualization of shell extensions. Actually shell extension virtualization is just one of the side benefits of JITV (Just-in-Time Virtualization – or “Dynamic Virtualization” as it is officially called.) Beginning with Office 2013, there was the capability of virtualization within a process being dynamically activated and de-activated on a per-thread process.
With SP2, this feature was extended to shell extensions AND ActiveX controls implemented as an in-proc COM object. This is why you will see injections of the App-V Hook DLL into Explorer or Internet Explorer even when no virtualized package is in use. This leads to an important statement: Just because the application is hooked, doesn’t always mean it is running virtualized if it appears as a process under the ProcessesUsingVirtualComponents registry value. This will be done at the thread level.
When an ActiveX OCX or a DLL that implements a shell extension is loaded from a native process or a process from another virtual application, App-V generates an additional virtual environment on demand linking the package containing the OCX or DLL with the process. Then dynamic virtualization is turned on for that particular thread. Once the thread exits, dynamic virtualization is turned off. If the said thread with dynamic virtualization spawns another thread, that thread too will be virtualized. This also helps to prevent RunVirtual collisions.
When a single native process attempts to launch within more than one primary virtual environment without connection groups, you have colliding virtual environments – and it is not pretty.
In the context of Internet Explorer, they look like this:
Often this will be accompanied by the illustrious “spinning donut!”
How to tell if you have a RunVirtual Collision:
- The native application is immediately unresponsive upon launch and it remains unresponsive.
- The launch of the native applications spawns multiple packages in use when no connection groups are configured. These are the collisions.
- The CPU will be completely pegged:
And the battle waging will be the native processes – usually at least one per package involved in the collision.
Finally, the smoking gun will be running LISTDLLS or Process Explorer against it looking for the actual executable for the virtual package. You will notice that while the native app is hooked, no virtual processes are able to start and get hooked (in this particular example, Java)
The cause will most likely be launching the application through a run virtual command (ie Process.exe /appve:<GUID>_<GUID>) configured to run inside one particular virtual environment – while at the same time – that same native application is configured to run virtual inside another virtual application environment using the RDS RunVirtual registry key.
In the case of the above example, that was the exact cause. Internet Explorer was added as a process in the RunVirtual registry key and was configured to run in the Java 1.4 package. If you ran a normal instance of Internet Explorer, everything behaved properly. However, if you ran a shortcut to Internet Explorer configured to run inside a separate instance of Java using the /appvve switch, then the collision occurs.