Fixing "LUA bugs", Part I
You have an application that you – or your users – need to run. It’s a normal app – it isn’t designed to perform system administration of your computer, but for some reason, it doesn’t work correctly unless it’s run from an account that has administrator-level access (see “What is a "LUA Bug"? (And what isn't a LUA bug?)”. But you don’t want your users running as admin. What to do?
The “workaround” most frequently chosen is simply to add the user to the Administrators group. Sometimes this approach is not decided by the IT department, but by some “helpful” HelpDesk technician: “Let’s see whether this fixes the problem.” The technician forgets to remove you from the Admins group, inevitably leading to another HelpDesk call within a few weeks: “HelpDesk, why is my computer running so slowly, and why are all these porn ads popping up whenever I log on?” (Answer: Because you’ve been running as admin!) Let’s just call this “workaround” a non-starter and not give it any further consideration.
Other common but sub-optimal workarounds are: 1) run the one program as administrator, or 2) run the program as a regular user, but after granting Everyone “Full Control” over the program’s installation folder and all of its registry keys under HKEY_LOCAL_MACHINE, and to all of HKEY_CLASSES_ROOT. Oh, and while we’re at it, grant the user the “Debug”, “Take ownership” and “Act as part of the operating system” privileges. These are seriously high-risk ways to get the program to run, and should be avoided.
So what do you do? In this mini-series of posts, I’ll lay out a systematic approach for working around LUA bugs that minimizes exposure. I’ll discuss approaches from most-preferred to least-preferred, with some of the pros and cons of each. By the way, while this guidance is targeted primarily to Windows XP, it will also work on Windows Vista.
#1: It is a bug – treat it like one and make the developers fix it!
This is the most preferred approach. If there is no legitimate business or technical reason for the app to require admin privileges, then failure of the app to work for a regular user account is a serious bug that compromises system security, stability and manageability. (Note: if the development team says something like “It’s mission-critical, so it has to run as admin”, or “it writes to HKEY_LOCAL_MACHINE, so it has to run as admin”, the correct response from you is, “You’re talking nonsense. Fix the bug!”)
Benefits of this approach:
Once it is fixed this way, you don’t need to carry forward any shims, tweaks or workarounds.
Developers may learn from the experience, and stop creating new LUA bugs. (Note: Developers running as admin are the #1 cause of LUA bugs!)
There are some drawbacks, though:
The expense in time and/or money may be prohibitive, particularly if you have limited resources and a lot of apps to fix. You have to consider the possibility of the app having to be rearchitected, and the possibility of new bugs being introduced in the process.
The developers and/or the source code may not be available. It may be 3rd party code from a company that no longer exists. The developers may be in rehab. Or jail. Or working for your competitor. Or they may be working on something “more important”.
#2: Application Compatibility Toolkit
Use the LUA Mode shims of the Application Compatibility Toolkit (ACT). (File and Registry Virtualization is the equivalent solution built into Windows Vista.)
The LUA Mode shims detect attempts to write to system-wide locations in the file system and registry and silently redirect them to per-user locations.
Benefits of this approach:
- It is easy to implement
The LUA Mode shims on XP often do not work (Vista’s Virtualization is a complete rewrite and will have much higher compatibility marks than XP’s ACT LUA Modes.)
The added complexity of the resulting underlying operations can make your troubleshooting more complicated when things don’t work.
The next 3 items (3a, 3b and 3c) are system changes that solve different specific issues, but share the common feature of not granting any elevated access to system-wide resources.
#3a: Copy specific HKCR keys to HKCU\Software\Classes
(Registry notations used here:
HKLM = HKEY_LOCAL_MACHINE;
HKCR = HKEY_CLASSES_ROOT;
HKCU = HKEY_CURRENT_USER)
Some background: Prior to Windows 2000, HKCR was just a symbolic link to HKLM\Software\Classes, which only Administrators can write to. In other words, operations performed on HKCR\.txt would actually occur in HKLM\Software\Classes\.txt. Windows 2000 introduced per-user registration data, so now HKCR is a merged view of HKLM\Software\Classes and HKCU\Software\Classes (which the user can write to). If a key exists in the latter, it takes precedence. So now an operation on HKCR\.txt will occur in HKCU\Software\Classes\.txt if that key already exists, otherwise it will occur in HKLM\Software\Classes\.txt as it had in the past.
The issue to fix: A number of applications write to HKCR at runtime to “reinforce” their file associations, COM registration data, etc., and raise an error if the write fails, even if the data they want to write is already there. The same data is written every time the app runs. If that same registration data were stored in HKCU\Software\Classes, then the write operations would succeed, without changing program behavior.
How to fix it: First you must identify the keys under HKCR that the application is trying to write to. (How to do that will be covered in later posts.) Export those keys to one or more .reg files (in Regedit, use File/Export, Selected branch). Using a text editor, replace all instances of
and save your changes. Import the edited .reg file into the registry of the user who needs to run the program.
Benefits of this approach:
This fixes issues where applications perform operations in HKCR that should have been done only during installation.
This approach is better than loosening access control on system-wide resources under HKCR (HKLM). Malware overwriting keys under HKCU will not affect operating system components or other users of the computer.
- It is not easy, with today’s tools, to identify HKCR writes as the source of LUA bugs, and exactly which keys are involved. (More on this in upcoming posts.)
Back in the days of Windows 3.x, before there was the Registry that we know and love, the OS and applications stored configuration and preference data to .ini (initialization) files, such as win.ini. Windows did and still does offer API-level support for .ini files via the “Profile” APIs (e.g., WritePrivateProfileString). Many apps (including some Windows applets) still use these APIs to try to write to .ini-formatted files, often in folders where Users are not supposed to write.
Windows NT 3.1 encouraged the migration from .ini files to the more scalable and manageable Registry, and provided a means for automatically redirecting .ini file reads and writes to registry keys. The internal implementation of the “Profile” APIs was augmented to use mappings found under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\IniFileMapping\. If a mapping for a .ini file is not found under that key, then the operation is performed in the file system as before.
The issue to fix: If access to an .ini-formatted file – via the “Profile” APIs – is the cause of a LUA bug, it can be remediated by adding a key under the IniFileMapping key to redirect access to HKCU. Note that IniFileMapping is under HKLM and requires administrative privileges to configure. The config specifics are described in the documentation for the “Profile” APIs, such as WritePrivateProfileString.
Benefits of this approach:
- This approach is better than loosening access control on system-wide resources in the file system. Malware overwriting keys under HKCU will not affect operating system components or other users of the computer.
- It is not easy, with today’s tools, to identify .ini-file access as the source of LUA bugs. (More on this in upcoming posts.)
A number of games depend on the “secdrv” device driver, also known as “SafeDisc”, from Macrovision. The secdrv driver that ships with Windows XP is a demand-start driver, which users are not allowed to stop and start, resulting in errors when accessed by programs. There is an update, available from Microsoft and from Macrovision that configures the driver to be loaded when the system starts so that the user does not need to start it. This change allows some games to work correctly for a non-admin user.
(Note that as of this writing, the Microsoft download page for this update says that “[t]his software will not alter or patch any component on your system, it will only change the startup state of the system component…” This is actually not true – it installs an updated driver.)
Benefits: Easy to implement, and no ACL changes to systemwide resources.
Drawbacks: None, really.
Coming up in Part 2:
#4: Loosening specific ACLs, and
#5: Running the one app as admin