Virtualization


Before we describe virtualization, we want to point something out. Virtualization is intended only as a bridge to assist with migration of legacy applications, and developers should not take advantage of it for new applications. Applications that require virtualization to work correctly will not be logo-certified for Windows Vista, and virtualization is not supported for native Windows 64-bit applications.

With that out of the way, virtualization is a feature that allows a legacy application to run as a normal user, when normally it would fail if the application were not run by an administrator. The biggest reason, by far, that applications fail to run as a user is that the application attempts to write configuration or application-specific data to protected locations of the operating system.

Warning 

Applications that allow virtualization are potentially attackable by other standard user applications because they can share relatively weakly ACLd shared folders. To disable virtualization, see the section titled, “How to Disable Virtualization for Your Application” later in this chapter.

The following code will fail unless it is run by an administrator or Power User on Windows XP SP2 because it’s trying to write to the Program Files directory. Yet it runs correctly on Windows Vista–as long as it’s a 32-bit process executed by a normal user:

 wchar_t wszPath[MAX_PATH]; if (SUCCEEDED(SHGetFolderPath(NULL,                               CSIDL_PROGRAM_FILES,                               NULL,                               0,                               wszPath))) {    PathAppend(wszPath, L"Savedgame.xml");    HANDLE hFile = CreateFile(                        szPath,                        GENERIC_WRITE | GENERIC_READ,                        0,                        NULL,                        CREATE_ALWAYS,                        FILE_ATTRIBUTE_NORMAL,NULL);     if (hFile == INVALID_HANDLE_VALUE ) {          // failed     } else {          // success          CloseHandle(hFile);          hFile = NULL;     } }

This code works correctly on Windows Vista because application file and registry writes are virtualized by the operating system; write operations to protected locations (in this case, the Program Files directory) are redirected. If you look in the Program Files directory after running this application, you will see no file. So where is the file? Take a look in the C:\Users\ username\AppData\Local\VirtualStore\Program Files folder. As you can see, the file write operation was redirected to a location the user can write to, and the application works correctly.

Tip 

If you navigate using Explorer to a directory that has virtualized files, you will see the words, “Compatibility Files” appear in the toolbar. If you click on this, you will see all the virtualized files.

You can see if a process is virtualized by looking in the Task Manager (see Figure 2-3). By default the Virtualization column is not displayed, but you can display it by:

  1. Launch Task Manager.

  2. Click the Processes tab.

  3. Click View.

  4. Click Select Columns.

  5. Scroll to the bottom of the list, and enable Virtualization.

image from book
Figure 2-3: Task Manager showing which processes support virtualization.

You can also determine if a process is virtualized with the following code:

 bool IsProcessVirtualized(__out bool& fVirt) {      HANDLE hToken = NULL;      bool fRet = false;      if (!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken))         return fRet;      DWORD IsVirtualized = 0;      DWORD cbLen = 0;      if (GetTokenInformation (             hToken,             TokenVirtualizationEnabled,             &IsVirtualized,             sizeof IsVirtualized,             &cbLen)) {          fVirt = !!IsVirtualized;          fRet = true;      }      if(hToken)         CloseHandle(hToken);      return fRet;   }

Virtualization is intended only to enhance application compatibility with existing programs. Applications designed for Windows Vista should not perform writes to system locations, nor should they rely on virtualization to provide redress for incorrect application behavior.

Tip 

You can look at important virtualization events in the Event Viewer. Open the Event Viewer, and expand Applications and Services Logs, then expand Microsoft, then expand Windows, and finally expand UAC-FileVirtualization.

When updating existing code to run on Windows Vista or writing new code for Windows Vista, developers should ensure that, during run time, applications only store user data under the locations noted in Table 2-2.

Table 2-2: “UAC-Friendly” Storage Locations for User Data
Open table as spreadsheet

Directory

Environment Variable

SHGetKnownFolderPath Folder ID

Purpose

C:\Users\user\AppData\Roaming

%appdata%

FOLDERID_RoamingAppData

Roaming Per-user data

C:\Users\user\AppData\Local

%localappdata%

FOLDERID_LocalAppData

Per-user data

C:\ProgramData

%programdata%

FOLDERID_ProgramData

Per-machine data

Virtualization is enabled only if the following conditions are met:

  • Process is 32-bit

  • Process is run by an interactive user

Virtualization is not enabled for:

  • 64-bit processes

  • Administrator processes

  • Services

  • Impersonated callers

  • Application manifest that has a requestedExecutionLevel setting

How to Disable Virtualization for Your Application

Sometimes you may want to disable file and registry virtualization, perhaps for debugging reasons. Better yet, you have fixed your application so it no longer relies on virtualization. Some customers disable virtualization to improve application manageability. There are many ways to disable application virtualization. We’ll discuss some of them here.

Create a Side-by-Side Application Manifest

If the application is unsigned and has no embedded application manifest, you can create a stand-alone application manifest file and save it next to the main executable.

Tip 

Note that Visual Studio often embeds a manifest in the compiled application. You can disable this by opening the project properties, expanding to the Manifest Tool option, clicking Input and Output, and then setting Embed Manifest to No.

If the application is named tool.exe, then save the manifest as tool.exe.manifest. The manifest should include the following string:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>   <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">       <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">         <security>           <requestedPrivileges>             <requestedExecutionLevel                level="asInvoker"                uiAccess="false"></requestedExecutionLevel>             </requestedPrivileges>           </security>        </trustInfo>     </assembly>

Use the noVirtualization shim

Microsoft has developed a series of “shims” that help remedy various application compatibility issues. One such shim is the noVirtualization shim available as part of the Application Compatibility toolset, which you can download from (Microsoft 2006b).

Programmatically Disabling Virtualization

Adding the following code to your main function will disable virtualization for your process.

 DWORD dwVirtEnabled = 0; BOOL ret = SetTokenInformation(hTargetProcToken, TokenVirtualizationEnabled,                                 &dwVirtEnabled, sizeof(dwVirtEnabled));

Change the Virtualization of a Running Process

This is not recommended, but it does work if it’s the only means you have.

  • Open Task Manager.

  • Select the Processes tab.

  • Right-click the process in question.

  • Check or uncheck the Virtualization option.



Writing Secure Code for Windows Vista
Writing Secure Code for Windows Vista (Best Practices (Microsoft))
ISBN: 0735623937
EAN: 2147483647
Year: 2004
Pages: 122

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net