We recently had an engineer report a strange exception when displaying .hta files via mshta.exe. If you embed the Windows Media Player OCX control (WMP) in a web page and then start playback of a file, you will get an exception like the following:

Windows - Bad Image
Exception Processing Message 0xc000007b Parameter 0x760892A0
0x760892A0 0x760892A0 0x760892A0

This issue always occurs on the 64 bit version of Windows Vista. It can also occur on the 32 bit version of Vista when certain older versions of firewall / anti-virus software are installed or if the machine is infected with certain viruses.

It took us a while to track this one down. Eventually we found that the exception is being caused by the MFPMP.exe process. This process is the secure audio and video playback process for WMP on Vista. The interesting thing is that WMP always uses MFPMP for all WMA, WMV, ASF and MP3 content regardless if it is protected with DRM or not. I talked to the guys on the WMP team about this. They said that they wanted to have a different playback path for non-DRM encoded files but decided that it was just much easier to have everything go through MFPMP.

The biggest challenge in keeping DRM content safe is finding ways to keep attackers from reading the decryption keys directly out of memory. Every DRM system has suffered from this attack vector, from Microsoft to Apple and everyone in-between. MFPMP uses the “Protected Environment” or “Secure Process” (PE) APIs that were added in Vista. These APIs allow the MFPMP process to be isolated. A process that is protected in this way cannot be debugged. You can’t connect a debugger to the process and peer into its inner workings.

Another attack that is used to read data out of a process is known as “DLL injection”. In this type of attack, rather than attaching a debugger the attacker finds a way to get their malicious DLL to run in the context of the process to be attacked. This attack takes many forms. MFPMP via the PE protects against this attack by requiring that all DLLs that run within the process to be “signed”. Signing is a way to watermark a DLL. When the MFPMP process reads in a new DLL it checks for this digital watermark or signature. If the signature is determined to be valid the DLL is loaded into the process. If the signature is not valid then MFPMP doesn’t allow the DLL to be loaded.

MFPMP’s rejection of un-trusted DLLs causes the error. In this case mshta.exe loads an .hta file. This file contains an embedded WMP OCX control. This control loads a standard ASF file. The WMP OCX control then attempts to play this file by starting up an instance of MFPMP.exe. While MFPMP.exe is starting up it attempts to load a DLL that is not properly signed. MFPMP.exe raises a “critical error” (Bad Image). This error is handled by the default error handler in the operating system (OS). This exception handler displays a dialog box that shows the “bad image” message.

The interesting thing is that if you use the same .hta file in Internet Explorer (IE) you don’t see the exception. The exact same order of operations holds true to IE as it does for MSHTA.exe. The main difference is that IE has code that explicitly suppresses the default error handler in the OS (SetErrorMode(SEM_FAILCRITICALERRORS )).  MSHTA.exe does not contain this code and there are no plans to add it.

You can confirm that you are experiencing this issue by going to Event Viewer=>"Windows Log"=>Security. Search the list for an entry labeled "Audit Failure". This entry should have the following message text:

Code integrity determined that the image hash of a file is not valid.  The file could be corrupt due to unauthorized modification or the invalid hash could indicate a potential disk device error.
File Name: xxxx

The “file name” section contains the name of the DLL that is being rejected by the MFPMP process. On Vista 64 this file might be named something like “wow64.dll”. This is an operating system file. On the 32 bit Vista OS this file will have the name of a 3rd party DLL. A number of older anti-virus and firewall applications use undocumented APIs to inject their DLLs into every process on the system. Since these 3rd party DLLs are not properly signed, MFPMP rejects them.

To resolve this issue on 32 bit versions of Vista you need to get the latest version of your anti-virus or firewall application. If upgrading does not fix the problem you may need to uninstall the 3rd party application. Or you can call your application’s vendor and ask them to stop using undocumented and potentially dangerous APIs. On Vista 64 there are no plans to properly sign wow64.dll to prevent this issue. We hope (although it has not been confirmed) that this issue will be addressed before Windows 7 ships.