User Interface Privilege Isolation - .NET
Hands-On Lab
User Interface Privilege Isolation - .NET
Lab version: 1.0.0
Last updated: 12/3/2010
Contents
Overview 3
Exercise 1: Identifying UIPI 4
Task 1 - Make Sure UAC is Active 4
Task 2 - Identify the Problem 5
Exercise 2: Solving UIPI Issues 7
Task 1 - Explore the Ping Pong Sample 7
Task 2 - Fix the Code 8
Summary 10
Overview
Objectives
In this lab, you will learn how to:
· Identify a User Interface Privilege Isolation (UIPI) issue
· Fix the UIPI issue
System Requirements
You must have the following items to complete this lab:
· Microsoft Visual Studio® 2008 SP1
· Microsoft Windows® 7
· Process Explorer from Windows Sysinternals (www.microsoft.com/technet/sysinternals)
Exercise 1: Identifying UIPI
In this exercise you will investigate two processes that communicate via windows messages, but where communication fails (at least in one direction) due to unequal integrity levels.
Task 1 - Make Sure UAC is Active
In this task, you will confirm that User Account Control (UAC) is active. This will allow the problem to occur.
1. From Start:
a. Click Control Panel.
b. Click User Accounts and Family Safety.
c. Click User Accounts.
d. Click Change User Account Control Settings. A dialog box similar to the following should appear.
Help
Alternatively, click Start, click Run, and type UAC. Then click Change User Account Control Settings.
2. Make sure the slider is set at the default level as pictured (you can set it to another level, but not to Never notify, as this disables UAC).
3. Click OK.
Task 2 - Identify the Problem
1. Navigate to the PingPongBroken\Debug folder.
2. Double-click BrokenManagedPingPong.exe. A blank window should appear.
3. Double-click the same .exe file again. You should see a message, “Ping Pong,” bouncing between two similar windows:
Help
This is the correct behavior. Both processes run with standard user privileges with the same integrity level. To verify this follow the next steps.
4. Open Process Explorer from Windows Sysinternals (www.microsoft.com/technet/sysinternals).
5. Right-click the process view header.
6. Click Select Columns.
7. Make sure the Integrity Level check box is selected.
8. Click OK.
9. Navigate to the BrokenNativePingPong.Exe processes and look at the integrity level.
It should be medium. This is the default integrity level of processes started with standard user privileges.
10. Close both Ping Pong windows.
11. Double-click BrokenManagedPingPong.Exe to run the first instance as before.
But for the second instance:
12. Right-click it.
13. Click Run as administrator.
14. Satisfy the UAC prompt presented. (Alternatively, you can just double-click ManagedPingPongLoader.exe and it will do both things automatically.)
Watch Out
You’ll find that the message, “Ping Pong,” no longer works.
15. Open Process Explorer as before and look at the integrity levels:
16. Running as administrator, the process is running with a high integrity level instead of normal integrity level. This is the cause of the problem. A process cannot send or post windows messages to another process with a higher integrity level.
17. Close both Ping Pong windows.
Exercise 2: Solving UIPI Issues
Task 1 - Explore the Ping Pong Sample
In this task, you will investigate the Visual Studio solution to understand what the code does.
1. Double-click the PingPongBroken solution.
Help
Visual Studio 2008 should start and load the solution. The solution contains four projects: two native and two managed. Each pair is the Ping Pong application itself and a convenient loader that starts one process with standard user privileges and the other with administrator privileges.
2. Right-click the PingPongForm.cs or PingPongForm.vb file and select View Code.
3. Scroll down to the NativeWrappers class.
Help
This internal class wraps some native functions for message registration and message passing. The PingPongFrom constructor registered the special message by calling the RegisterWindowsMessage function, to obtain a global (technically, globally to the process’ Windows Station) message id for inter-process communication. The resulting message, _message, is the one posted between windows of the two running processes.
4. An override of the WindowProc method in the PingPongForm class handles the registered message and uses a timer to alternately display the message parts with 500 msec intervals.
5. The Main method searches for another instance of the same executable by looking for the existence of another window with the same caption (using a P/Invoke around the FindWindow function).
Task 2 - Fix the Code
The PostMessage function used for message passing fails if its intended message is to a window belonging to a process with a higher privilege level. However, we can use a message filter to let some messages through:
1. Add a P/Invoke wrapper around the ChangeWindowMessageFilter native function, which can filter messages regardless of privilege levels.
2. Add the following code In the NativeWrappers class:
C#
public enum ChangeWindowMessageFilterFlags : uint {
Add = 1, Remove = 2
};
[DllImport("user32")]
public static extern bool ChangeWindowMessageFilter(uint msg,
ChangeWindowMessageFilterFlags flags);
Visual Basic
Public Enum ChangeWindowMessageFilterFlags As UInteger
Add = 1
Remove = 2
End Enum
<DllImport("user32")> _
Public Shared Function ChangeWindowMessageFilter(ByVal msg As UInteger, ByVal flags As ChangeWindowMessageFilterFlags) As Boolean
End Function
Help
After the message registers in the form’s constructor and before the first message posts, use the newly added wrapper to let the registered message pass through, regardless of privilege levels:
3. Add a call to NativeWrappers.ChangeWindowMessageFilter with the flag ChangeWindowMessageFilterFlags.Add:
C#
_message = NativeWrappers.RegisterWindowMessage("BALL");
if(_message == 0)
Close();
else {
NativeWrappers.ChangeWindowMessageFilter(_message,
NativeWrappers.ChangeWindowMessageFilterFlags.Add);
NativeWrappers.PostMessage(Program.hOtherForm, _message, Handle,
IntPtr.Zero);
}
Visual Basic
_message = NativeWrappers.RegisterWindowMessage("BALL")
If _message = 0 Then
Close()
Else
NativeWrappers.ChangeWindowMessageFilter(_message,
NativeWrappers.ChangeWindowMessageFilterFlags.Add)
NativeWrappers.PostMessage(Program.hOtherForm, _message, Handle,
IntPtr.Zero)
End If
4. Build the project and test it with ManagedPingPongLoader.exe.
It should work as expected. The complete solution is in the PingPongFixed folder.
Summary
In this lab, you learned how to diagnose UIPI issues using Process Explorer, and how to allow messages to filter to applications with higher privilege levels.
For more information, please refer to:
· Application Compatibility Cookbook: http://msdn.microsoft.com/en-us/library/bb963893.aspx
· The Windows Vista and Windows Server 2008 Developer Story: http://msdn.microsoft.com/en-us/library/aa905330.aspx
· Edgar Barbosa: Windows Vista UIPI: http://www.coseinc.com/en/index.php?rt=download&act=publication&file=Vista_UIPI.ppt.pdf
10