What is the significance of changing the registration for CLSIDs to point to a private copy of MSXML3?


A customer reported that several of their applications stopped working after they installed a third-party program, let's call it Contoso Deluxe. They found that the Contoso Deluxe program, as part of its installation, rewrote some CLSID registrations. For example, HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{F5078F37-C551-11D3-89B9-0000F81FE221}\InProcServer32 is normally %SystemRoot%\System32\msxml3.dll, but installing Contoso Deluxe changes it to C:\Program Files\Contoso\Common\msxml3.dll.

The customer wanted to understand the significance of this change.

The significance of this change is that the Contoso Deluxe program hijacked a bunch of objects that normally belong to the MSXML3.DLL that comes with the operating system, redirecting requests for those object to the private copy of MSXML3.DLL that comes with the Contoso Deluxe program.

I have two theories for why the Contoso Deluxe program does this. The more charitable theory is that the developers wanted to redistribute MSXML3.DLL and didn't know that there were specific instructions on how to do it correctly. Instead, they just packaged the DLL with their program and blasted the registry keys as part of installation.

If that's the case, then they should have followed the installation and redistribution instructions, so that the MSXML3.DLL file gets installed properly. Part of that proper installation is "If you see an existing copy of MSXML3.DLL that is newer than the one you are trying to install, then use the existing copy."

Another theory is that the developers found some sort of problem with newer versions of MSXML3.DLL and decided to solve the problem by locking their program to a specific version of MSXML3.DLL by packaging it with the program and directing all MSXML objects to their private copy of MSXML3.DLL.

If that were indeed their intention, then they tried to apply a global solution to a local problem. Because what they did was redirect all MSXML objects for all applications in the system to their private copy of MSXML3.DLL, even though they really wanted to redirect the object only for their program. The proper way to do this is to use an application manifest and registration-free COM to redirect the classes just for their program. (Of course, the real proper way to solve the problem is to figure out why their program doesn't work with newer versions of MSXML3.DLL.)

Note also that a private copy of MSXML3.DLL will not get serviced by Windows Update, which means that machines with that private copy will not receive security fixes to MSXML3.DLL. (More accurately, they will receive security fixes to C:\Windows\system32\msxml3.dll, which is useless because the system is using C:\Program Files\Contoso\Common\msxml3.dll.)

We advised the customer to engage with Contoso and work with them to fix the Contoso Deluxe program so that it neither breaks every program that uses MSXML3.DLL, nor prevents Windows Update from fixing security issues in MSXML3.DLL.

Comments (22)
  1. pc says:

    I always thought that Windows File Protection was overkill in its approach to dealing with poorly-written setup programs, but after reading stories like this I'm not sure it goes far enough…

  2. xcomcmdr says:

    Nuking well known system CLSIDs should be illegal, I hate it when a program "replaces" a system file.

    That was "fine" back on Windows 98 And by fine I mean it worked for a while before it crashed an app or the OS itself

    Just. Stop. Doing. That.

  3. Joshua says:

    I wonder what the bleep I would do if I found myself in a case where an update from MS was breaking my program and I could trace it to a bug in the update and I had no hope of getting a fix out of MS quickly.

    Trying to work out how to pin a specific DLL version seems surprisingly reasonable, as does doing it wrong as this stuff is so non-discoverable.

    1. Garrett says:

      Joshua:

      I wonder what the bleep I would if I found myself in a case where getting to McDonalds was broken and I could trace it to road construction.

      Bulldozing your living room seems surprising reasonable, as does bulldozing the living rooms of all your neighbors as routes to McDonalds are surprisingly non-discoverable.

    2. Max says:

      That's the risk you take when you introduce a dependency on files you don't control.

  4. Ramón Sola says:

    I remember some old versions of a well-known "portable document" viewer which modified the registry keys of the DWebBrowserEvents2 interface and locked down their permissions. These changes to the registry and a bug in the Internet Explorer 7 setup program contributed to installation failures on localized Windows XP and Windows Server 2003 systems.

  5. Yuhong Bao says:

    Yea, it has never been an supported practice and MSXML3 has considered a part of Windows since WinXP I think.

  6. This is one of the reasons that traditional Windows apps have to go. An open system in which every app does whatever it likes definitely does not fit with the needs of the 21st century.

    1. xcomcmdr says:

      Apps don't do whatever they like since Windows NT (1993).

  7. fm says:

    This problem is also solved by Appx's, right, since that registry change is contained just for the app?

  8. Henri Hein says:

    Isn't that precisely the sort of problem SxS was designed to solve?

    1. Yuhong Bao says:

      I think "registration free COM" is basically SxS.

  9. jimbo1qaz says:

    Am I correct that (Linux-side, not Windows) NixOS (programs) and Docker (containers) attempt to eliminate dependence of programs on global configuration?

    1. Brian says:

      In Windows-world, global configuration has been going away for a while. COM has supported "registration free COM" (referenced by Raymond) since, if I remember correctly, XP. There was an earlier version in Win2k I think. Nearly all apps based on the .NET Framework generally do not include global configuration in their installation, and the move to local config has become more pronounced over time. I haven't used the Universal Windows stuff yet, but I'd be *very* surprised if any global configuration was required in that Framework.
      With containers, you can do all the global configuration you want - no one else will see it - the "global" world your app sees is local to your app.

      1. Kevin says:

        > With containers, you can do all the global configuration you want – no one else will see it – the “global” world your app sees is local to your app.

        Even within a container, it is a lot more reliable to do local configuration than pseudo-global configuration, because it makes it safer to fiddle with the container's base image and/or install multiple applications into one container (which is unideal but may be necessary to deal with a variety of practical concerns).

  10. DWalker says:

    "Deluxe" in the product name "Contoso Deluxe" means that it is enterprisey enough to take over the functions of MSXML3.dll. If you think you need for MSXML3.dll to do anything in the future that it doesn't do now, you are wrong because Contoso Deluxe has anticipated your needs!

  11. xp.client says:

    That's awful. I see that key as protected by Windows Resource Protection so did that app's installer take ownership and then modified it? Maybe Windows Defender should show a notification to the user that system resources are changing ownership.

    1. GregM says:

      My guess is that it's protected *now*, possibly as a direct result of this report.

  12. JoeWoodbury says:

    My solution to all msxml issues is to use PugiXml. (mxsml isn't bad in .NET, but is sure a nightmare in C++.)

    1. Henri Hein says:

      Huh. I have used msxml from C++ and been pretty pleased with it. I haven't used PugiXml, but plenty of other XML libraries, and never one that made me want to not use msxml when it was an option (ie, any Windows-only project).

  13. Johan says:

    For even more fun uninstall Contoso Deluxe..

Comments are closed.

Skip to main content