I suddenly seem to be getting asked by a number of software vendors to help them support customers that are using App-V. This is fantastic! Vendors that want to support App-V? We have dreamed of this for 15 years now. I am thinking that four is perhaps more than just a blip, maybe it is a trend. I certainly hope so.
This week’s vendor (I can’t mention them by name) approached me because of a problem at a customer site. Unlike other ISVs to approach me recently, this one wasn’t having their software packaged for App-V, but still had a problem. The customer was natively installing their software on the system. But on systems with App-V installed, their software didn’t work.
The software consisted of a back-end windows service and an Internet Explorer plug-in. If the user was published any App-V packages that included IE plug-ins (or probably Browser Helper Objects or ActiveX components), the app broke. Through trial and error they had found that if they could get the customer to enable COM visibility and disable Object renaming in the sequencer for ALL of those packages, the problem went away. The customer wasn’t satisfied with that solution and the vendor wanted to know what was going on.
I immediately suspected that the issue had nothing to do with COM visibility and everything to do with Named Objects. I was right. So what are Named Objects and just what is this checkbox in the sequencer for anyway?
Sidebar on Named Objects
The kernel of the Microsoft operating system manages a variety of resources for the user mode processes. It does this for efficiency and/or because multiple processes might share the resource. Often, the resource (not resource type) is accessed by a name, and that it what we call “Named Objects”.
The most common form of a named object might be a file handle, where the name is the full path to the file. The process wants to open a file, but it is the Windows System cache that actually opens the file and manages what portions are currently in virtual memory. While file handles are named objects that you are familiar with, it turns out that App-V deals with files via the Virtual File System and Copy-on-Write subsystems, so this isn’t what we are talking about when we talk about named objects in an App-V world. Microsoft doesn’t really document what App-V does with Named Objects, so I guess it is on me to explain what I think it does.
The image on the right is a list of the types of objects supported by the Windows 10 operating system (it is taken from I home-grown tool that I wrote that extracts the information from an unpublished kernel interface).
Long ago, a lot of software applications were written for a single user desktop OS and didn’t take into account that multiple users might want to run the app on the same OS, and maybe at the same time. So when we built SoftGrid (the original name for App-V), we decided to intercept the calls to create these named objects and change the name (an operation called “remapping”). In App-V 5.x, if a virtualized process creates or opens one of these named objects, the software remaps by changing the names uniquely for the virtual environment it is running under. App-V enhances the name by prepending the characters “sg” followed by a long unique identifier for the virtual environment (a 16 character hash) and an underscore.
Certain kinds of named objects, such as named pipes, tend to be used more with inter-process communication and signaling, and when that occurs it is important that both processes use the same name. As long as the named object is only used by processes inside an App-V virtual environment, the app works normally when the object is renamed.
But the operating system includes all sorts of named objects created by the kernel or windows services that are part OS, so their end of these objects is never virtualized. Over the years App-V has developed a list of these and provides a registry exclusion list that exempts certain names from remapping by the App-V client, which makes those object work.
By the way, a remapping process also occurs for isolated COM objects in a package, although in that case a different dynamic CLSID Guid is created instead (there is also a COM CLSID exclusion list in the registry). Together, along with the VFS file system spoofing, we achieve a completely isolated virtual environment that internally works just like the native installation but can’t get messed with by outside processes. There is also something referred to as “side-by-side privatization” which fits in this basic category (but not for discussion today).
Why we use App-V
While we don’t see many applications that cause “dll hell” being deployed these days (most that are still in use are over 10 years old and were likely developed in-house and will need to be retired rather than upgraded), we still see a lot of applications not fully implemented for simultaneous use on the same system. Most apps today, understand the concept of different users and properly implement HKLM/HKCU and use the user’s profile fairly correctly. But many still fail if you put them in RDS because they don’t make use of session space. Still many more fail, typically with an occasional unexplained hang or crash, if you run multiple copies within the same user session (on RDS or desktops). And often we want to allow the user to run two different versions of the same application, which pretty much never works without application virtualization. This is why we use App-V; to make the software more predictable by limiting the dependencies on other stuff sitting around and/or running at the same time.
But sometimes we want integration outside of the bubble. The rewrite in App-V 5 was precisely to create more opportunities for integration. Giving us more integration points (“extensions” in App-V terminology) with other parts of the OS, other applications, and the user. With that integration, we also have some granular controls over that integration. 90% of the time we don’t need to think about those controls, but sometimes we do.
Back to the Problem
To protect the innocent, I’ll use a different software application from someone other than the software vendor that I was working with. I will use the excellent web sniffing tool from Telerik called Fiddler.
Fiddler, like the ISV software I was dealing with, has both an external process and a plug-in to Internet explorer. With Fiddler, the external process is a standard user process that can be started from the start menu rather than a Windows service, but that doesn’t matter for our purposes.
Fiddler, like the ISV software, is also completely virtualizable with App-V. Both work like a champ if you create and deploy an App-V package containing the software. Both also work great is you create a Connection Group with the package and with the other Internet Explorer add-ons.
The problem with the ISV app is seen if you natively deploy their app and use App-V for other Internet Explorer plugins. Both for Fiddler and the ISV, the external process can end up running outside of the virtual environment for Internet Explorer.
- With the ISV software, the service auto-starts and is pre-existing and is obviously outside of the virtual environment.
- With Fiddler, we can start the fiddler process by using a toolbar button within iexplore, in which case fiddler will be started in the virtual environment and work just fine.
- But if you start the Fiddler process from the start menu, and start iexplore.exe in a bubble, you have a mixed situation and a potential for a problem similar to the issue experienced by the ISV app. As it turns out, Fiddler does not do this but I will still use it to demonstrate the technique to solve the problem the ISV had. (Fiddler uses an IE exposed COM object. Remember that IE is native so the in-process COM dll is available for Fiddler to access). So let’s Fiddler did use a shared named object and see how we resolve the issue.
For the vast majority of software applications, one part being sucked into an App-V bubble is no problem. When those two processes communicate with each other using something like DDE or OLE, it works great. When they need to use COM, sometimes we want to integrate the COM (publishing the objects outside of the bubble and disabling the GUID remapping. If they communicate using a named object, there can be problems.
We can see this behavior by running the virtual application in the runtime analyzer of AppV_Manage (a free tool available from our website). The image below is of a virtualized Internet Explorer Plug-in package showing the various processes that run.
You will notice that there are multiple iexplore.exe processes, and a rundll32.exe process colored blue. The blue color lines on the Timeline indicate that the process is part of the virtual environment (#55). There are two iexplore.exe processes because multi-tabbed browsers usually use one process for the overall frame and then individual processes for each tab (we only had one tab open). The Mavinject32 processes you see were short lived (under 25 ms each) and are part of the App-V client that injects some client dlls into virtualized processes. The Fiddler process is colored in green in the image, indicating that it is not virtualized.
We can see the full command line of each of the processes in the Processes section of the display (shown above). Below that on the display (not shown here)is the Images Loaded section. If we open up the process entry in the Images Loaded section of the tool we can see the various dlls loaded by the virtual process (useful if you want to be sure which copy of a dll is in use, or if any Native Images are in use).
COM remapping can be seen in the v.COM section of the tool display:
And Object remapping can be seen in the v.Objects section:
(Note that the last line above indicates “not remapped” because it was already remapped. The original request created the Mutex and returned a handle to the process, and the process would have been unaware of the renaming. The process later used that Mutex handle, which was already tied to the remapped name).
Using the Manage Add-ons feature of IE itself, we can verify that both plug-ins are loaded (the “App-V Usage” that we intended to virtualize and “Fiddler” that came along for the ride):
What Happened to the ISV
What happened to the ISV was that the external windows service created a named pipe, and if they had called the pipe “Fred” (a fictitious name), it would appear as a named object of type “Device” and named “\Device\NamedPipe\Fred”.
In the analyzer trace v.Objects secton, we could see that the internet explorer process was attempting to open as Fred, but it was being renamed.
Because the service was not virtualized, we could not see any entries for object names in the AppV_Manage Runtime Analyzer. But we can using the Microsoft SysInternals tool ProcessExplorer. You need to start ProcessExplorer using the RunAs Administrator option, then use the View menu to enable the lower pane view to Handles. Click on the process in question. The image below shows a number of named pipes used by an App-V client process:
Armed with this information, we could clearly see the name mismatch. In this ISV’s case we could also have seen the mismatch just using ProcessExplorer alone, because the plugin kept the renamed named pipe handle open. Usually, an app would have immediately closed the handle and thrown an error, making it nearly impossible to see the renamed object in ProcessExplorer (it only shows currently running processes and currently open handles). So it’s nice that the Runtime Analyzer provides a history of the actions.
Possible solutions for the ISV:
There are four main solutions for this vendor to support their customers that use App-V:
- Recommend that the customers virtualize their software in a package and use a Connection Group with any other package that uses IE. App-V will virtualize the service along with IE and the problem is solved.
- Request that the customers disable object renaming in all IE plugin packages. Nobody likes the idea of opening back up those packages, so this option is pretty much dead-on-arrival. And I am not a fan of just disabling all of the object renaming without understanding the impact. Issues created this way will be the hardest to diagnose (which is why you used App-V to begin with).
- Request that the customers add a new entry in the system registry that adds an additional exclusion to the object exclusion list (HKLM\Software\Microsoft\AppV\Subsystems\ObjExclusions). As we can see in the standard list in App-V 5.1, it turns out that the value name for the entry doesn’t really need to be the next number in the list after all, just unique, so I am recommending the ISV suggest using their already unique named object for the value name and value. This change can be pushed out via any method, including group policy preferences, or as an add-package script in one or more of those IE addon packages.
- Request that Microsoft add the exclusion to the standard exclusion list in the next client release. We don’t yet know what the process is to make this request, but I’m working on it.
For Your Action
So the next time you find that you can fix a problem by checking the checkbox, consider finding the actual problem named object and excluding it.
If you are putting the software into a package, starting with App-V 5.1 you can also consider editing the internal AppXManifest file and adding the exclusion to only that package. The checkbox simply adds a wildcard exclusion of “*” to this file. You could check the checkbox, export and edit the file to change the “*” to the name you want excluded. The client uses regex against these names, so standard wildcards may be used. Save the file and import it back in. Anything in the list is considered an addition to the client registry stored exclusion list.
PS: It took me five times as long to write this up than to diagnose the ISV’s problem!