Thoughts from the EPS Windows Server Performance Team
Useful Microsoft Blogs
com·pat·i·ble adjective \kəm-ˈpa-tə-bəl\ : capable of existing together in harmony
What is a Shim?
A shim is one of the very few four-letter words in use by Microsoft that isn’t an acronym of some sort. It’s a metaphor based on the English language word shim, which is an engineering term used to describe a piece of wood or metal that is inserted between two objects to make them fit together better. In computer programming, a shim is a small library which transparently intercepts an API, changes the parameters passed, handles the operation itself, or redirects the operation elsewhere. Shims can also be used for running programs on different software platforms than they were developed for.
How Shims work.
The Shim Infrastructure implements a form of Application Programming Interface (API) hooking. The Windows API is implemented using a collection of DLLs. Each application built for Windows imports these DLLs, and maintains a table of the address of each of these functions in memory. Because the address of the Windows functionality is sitting in a table, it is straightforward for the shim engine to replace this address with the address of the shim DLL instead. The application is generally unaware that the request is going to a shim DLL instead of to Windows itself, and Windows is unaware that the request is coming from a source other than the application (because the shim DLL is just another DLL inside the application’s process).
In this particular case, the two objects are the application program and Windows, and the shim is additional code that causes the two to behave better together, as shown below:
Figure 1 Before the shim is applied, the application interacts directly with Windows.
Figure 2 After the shim is applied, the application interacts with Windows indirectly; the shim code is injected and can modify the request to Windows, the response from Windows, or both.
Specifically, it leverages the nature of linking to redirect API calls from Windows to alternative code—the Shim. Calls to external binary files take place through the Import Address Table (IAT). Consequently, a call into Windows looks like:
Figure 1 Application calling into Windows through the IAT
Specifically, you can modify the address of the Windows function resolved in the import table, and then replace it with a pointer to a function in the alternate shim code, as shown in Figure 2.
Figure 2 Application redirected to the shim prior to calling Windows
This redirection happens for statically linked .dll files when the application is loaded. You can also shim dynamically linked .dll files by hooking the GetProcAddress API.
Why Should we be using Shims
This is the cost-saving route—help the application by modifying calls to the operating system before they get there. You can fix applications without access to the source code, or without changing them at all. You incur a minimal amount of additional management overhead (for the shim database), and you can fix a reasonable number of applications this way. The downside is support as most vendors don't support shimmed applications. You can't fix every application using shims. Most people typically consider shims for applications where the vendor is out of business, the software isn't strategic enough to necessitate support, or they just want to buy some time.
For example, a very commonly used shim is a version-lie shim. To implement this shim, we intercept several APIs that are used to determine which version of Windows the application is running on. Normally, this information is passed on to Windows itself, and it answers truthfully. With the shim applied, however, these APIs are intercepted. Instead of passing on the request to Windows, a different version of Windows is returned (for example, Windows XP instead of Windows 7). If the application is programmed to run only on Windows XP, this is a way to trick the application into believing it’s running on the correct OS. (Frequently this is all that is necessary to resolve an application compatibility problem!)
There are a huge number of tricks you can play with shims. For example:
NOTE: As shims run as user-mode code inside a user-mode application process, you cannot use a shim to fix kernel-mode code. For example, you cannot use shims to resolve compatibility issues with device drivers or with other kernel-mode code. (For example, some antivirus, firewall, and antispyware code runs in kernel mode.)
When can we use a Shim:
Creating an Application Compatibility Shim
If you are trying to run an application that was created for 2000 or XP and had problems running in Windows 7, you could always turn on compatibility mode for the executable on your machine. However if you are trying to create a shim that could be used on other machines as well, you could use the following instructions to create the shim and send it. It is a very small size and once executed, will always be associated with that executable on that machine.
ACT is the Application Compatibility Toolkit. Download it from here: http://www.microsoft.com/downloads/details.aspx?familyid=24da89e9-b581-47b0-b45e-492dd6da2971&displaylang=en
Once we launch the Compatibility Administrator Tool, from Start Menu – Microsoft Application Compatibility Toolkit :
Right-click on New Database:
Choose Application Fix here. In this below dialog, give the application details and the executable you would want to fix:
When you press the next button, you will get to see the list of the compatibility modes listed by default. If you have an issue with just version incompatibility then choose the version in which the application was working earlier.
At this point I have already determined that Windows 2000 compatibility mode will work for this program.
In the list box, scroll down and select “Windows 2000”
In the next window (when you have combination of shims to be chosen). As shown below, you have lots of shims to choose from. Select all the shims which would fix your application.
Click on Finish. This will give you the complete summary of the application and the fixes applied.
Now you need to save this shim database file (A small database including the shim information is created), and install it. You can either install it by right-clicking on the shim and pressing the install button, or by using a command-line option, sdbinst.exe <database.sdb>.
NOTE: “sdbinst.exe” is already located by default in c:\windows\system32
Once the Application Compatibility Database is installed, we can run the program from the location specified earlier (in the first window). Now the program should be running in the Compatibility mode that you specified during the process.
I think the new ACT toolkit is OK, but I feel it's much better to process applications using tools from AppDNA or other vendors in this space. In our experience this has delivered a much higher return in accuracy plus covers more of the technologies we are looking to adopt.
Is there a place online or in the documentation that explains each shim similarly to the examples you gave in the article?
Pretty informative, will use it in my cases.
Is there a way to tell the installer that the installation account is member of a specific group?
In our case we delegated some AD management tasks to a delegation group but the installation account checks group membership of Enterprise Admins.
Thank you for your feedback
Getting this error:
Shim database version C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319 doesn't have a matching runtime directory
For more information, see Help and Support Center at go.microsoft.com/.../events.asp.
Can you let me know how to fix this.