Visual C++ 2005/2008 and Manifests…
January 18, 2009
It is interesting to see how Microsoft put a lot of effort in isolating DLLs to solve the long-hated problem of “DLL hell” (wherein a program depends on an exact version of a DLL, no newer, no older.) This, however, also brings a problem: security updates may not be propogated to older DLLs.
Take the Visual C Runtime DLL, msvcr80.dll , as an example. Its internal structures haven’t changed with every build. The problem here is that side-by-side lookups in XP and Vista check the versions to the build number, and ignore the DLL if its version numbers are different, even a build number. So there is a possibility that security updates with newer builds (e.g., 8.0.50767.163 from 8.0.50767.42) will not be propagated to the older versions.
Worse, if the application has no manifest (e.g., legacy apps) or the version numbers indicated in the manifest and the DLL’s numbers do not match, the result will be an initialization failure at start-up (because the CRT DLL will fail the initialization routines upon detecting either of the two conditions mentioned.)
Like I’ve mentioned in a previous entry, having two different CRTs in the same application will most likely catch the end-user by surprise, through such messages as fatal CRT memory corruption. I’m still developing the “proxy” CRT (this one is NOT the actual CRT; the actual CRT is Windows’ system CRT, msvcrt.dll .) Note that I do not use manifests in the “proxy” CRT DLL; let all applications, older or newer, get the security update.
Visual Studio 2008 and Application Compatibility
January 4, 2009
I’ve noticed that Microsoft has stopped supporting the entire Win9x series (those that run on top of DOS – Win95, Win98, WinME) in VS 2008. Also, a few global variables have been removed (such as _winver). In my opinion, these allowed the programmer to get OS version numbers right using the CRT. That’s easy, at least for me.
If I’m not mistaken, VS 2003 was the last to support Win95; and VS 2005 (which I am using) was the last to support Win98/WinME. With VS 2008, you are forced to target Win2000 or later (WinNT 4.0 is not supported). But maybe the developers of Visual Studio should be aware that these “legacy” Windows OSes are not yet shelved up for indefinite storage (maybe Win95 on the shelf will not be a big suprise, but Win98 systems still exist up to this day, in PCs used for automation, for instance.)
Windows 98 was used in automation computers, since this ran on top of DOS, and DOS allows a program to directly access the hardware via simple memory location reads/writes. This functionality is important with certain applications of automation wherein direct hardware control is a must; an example maybe a part of a power plant.
Windows NT/2000/XP have the additional advantage of security; although this helps prevent hackers from breaking into the PC and turn it into a “zombie,” these security checks may unnecessarily slow down the program, and may sometimes become detrimental .
Note that I think Windows 95 is not used on a single computer (Even most Win9x-only devices don’t support Windows 95.)
Well, we are at the mercy of Microsoft, since they can do whatever they want – even breaking compatibility with existing applications (this is what they did in Windows Vista, using User Account Control.) But Microsoft shouldn’t do that breaking – eventually, customers will not buy a new version of their Windows operating system if they know their current applications won’t work on that new version of the OS; it’s very likely Microsoft’s efforts on improvement (such as security) will go to waste, since customers aren’t going to use the new version.
You may think of me as a hypocrite (since I’m now using Visual Studio 2008), but I’m trying to generate a Visual C++ 2008 CRT DLL proxy to the system CRT using Visual C++ 2005 (because this version, at least, supports Windows 98/ME in any case. I still have that copy installed on my PC, although only the Express Edition.)
I like compiler upgrades for their security, but I don’t like them if they are going to break support for Windows versions that are still in use (Windows 98, 2000, XP, Vista), and a workaround is virtually impossible.
On the Visual C++ .NET DLLs…
January 2, 2009
One would notice that many applications compiled with Visual C++ 2002 or later would have the Visual C runtime DLLs in their private folders. As mentioned in KK’s blog, this approach doesn’t allow for central servicing.
Examine the code of one differential CRT DLL (say, msvcr90.dll), and that of the Windows CRT DLL (msvcrt.dll) – many of the functions haven’t changed through the years. This results in duplicated code in two different binary images, which wastes space. Exception handling can change, yes, but many of them still reference C Library functions (which hasn’t changed).
In that light, I decided to write a “proxy” DLL to make them use the Windows OS CRT.
There is one more common issue when using “legacy” DLLs (those compiled with VC6) with images produced by the VC7+ compilers: Heap corruption. Each CRT instance has its own heap, and even passing pointers between two different instances of the same identical CRT DLL is very likely going to result in a runtime failure. Examine again a differential CRT DLL with the Windows CRT DLL, and you will find that memory allocation functions (such as operator new[] and operator delete[]) are duplicated. To eliminate this problem, I also decided to use the Windows CRT’s memory heap instead and provide code-wraps and forwards required by the new VC7+ code.
By the way, I would greatly appreciate contributions in finding the functions that have been added after VC6.