目標
本實驗中你將學到:
• 識別用戶界面隔離級別(UIPI)問題
• UIPI 問題修復
系統需求
完成本實驗必須具有如下軟件:
• Microsoft Visual Studio 2008 SP1
• Microsoft Windows 7
• Process Explorer from Windows Sysinternals (www.microsoft.com/technet/sysinternals)
練習 #1 識別 UIPI
在本實驗中將研究兩個使用windows消息進行通信的進程,因為不同的完整性級 別(integrity level)通信失敗了(至少是單方向失敗)。
任務 1 —確認UAC 被激活
在這個任務中要確認用戶帳戶控制是激活狀態。 這將允許顯示問題。
1.點擊 Start:
a.點擊 Control Panel.
b.點擊 User Accounts and Family Safety.
c.點擊User Accounts.
d.點擊 Change User Account Control Settings。此時顯示一個類似於下圖的對話框
幫助
你 也可以通執行:點擊 Start,點擊Run,輸入UAC。點擊Change User Account Control Settings。

2.確認滑動條如圖所示設置為default級別(也可以設置一個別的非Never notify的級別 ,因為這會禁用UAC)
3.點擊OK。
任務 2 – 識別問題
1.轉到PingPongBroken\Debug 文件夾。
2.雙擊BrokenManagedPingPong.exe。顯示一個空白窗口。
3.再次雙擊同一 .exe文件。如下圖所示可以看到消息 Ping Pong,”在兩個窗口之間跳轉 。


幫助
這是一個正確的行為。兩個進程都使用同一個完整性級別的標准用戶權限。在下一步操作 中可以確認這個。
4.打開來自Windows Sysinternals的 Process Explorer (www.microsoft.com/technet/sysinternals ).
5.右擊進程查看頭。
6.點擊 Select Columns.

7.選擇Integrity Level復選框。
8.點擊OK。

9.轉到BrokenNativePingPong.Exe進程查看其完整性級別
應該為medium。這是標准用戶權限啟動的進程的默認完整性級別。
![]()
10.關閉Ping Pong窗口。
11.雙擊 BrokenManagedPingPong.Exe使第一個進程如前一樣運行。.但是對於第二個實例
12.右擊它。
13.點擊Run as administrator。
14.同意UAC的提示信息。(或者也可以雙擊ManagedPingPongLoader.exe ,則這兩個步驟 都已完成)
注意
此時消息“Ping Pong”無法工作了。
15.象之前那樣打開Process Explorer查看它們的完整性級別
16.由於是作為管理員,其進程現在以high而非normal的完整性級別在運行。導致問問題 出現。進程不能將windows 消息發送到另一個具有更高完整性級別的進程。
17.關閉兩個Ping Pong窗口。
練習#2 :解決UIPI 問題
任務 1 –浏覽Ping Pong 示例
本任務通過研究Visual Studio解決方案來理解代碼所做的工作。
1.雙擊PingPongBroken解決方案。
幫助
Visual Studio 2008啟動並裝載解決方案。解決方案包含四個工程:兩個為本地的兩個為 托管。每一對Ping Pong應用程序和一個便捷裝載器使用標准用戶權限啟用一個進程,使用管 理員權限啟用另一個進程。
2.右擊PingPongForm.cs文件選擇View Code。
3.滾動到NativeWrappers類的下方。
幫助
這個內部類包裝了一些本地函數用於消息注冊和消息傳遞。PingPongFrom構造器通過調用 RegisterWindowsMessage方法注冊特定的消息以得到一個全局(從技術上講,是進程的 windows工作站全局)消息id,用於進行內部進程通信。結果消息_message即兩個運行的進程 窗口之間傳遞的消息。
4.PingPongForm 類中的WindowProc 方法有一個重載用來注冊消息,使用(計算器) timer可選地將發關間隔設置為500毫秒。
5.Main方法通過搜索同名窗口查找同一可執行程序的另一實例(在FindWindow函數之上使 用P/Invoke )。
任務 2 –修復代碼
PostMessage函數用於當目標消息屬於更高權限級別時進行傳遞導致的信息失敗,無論如 何我們可以使用消息穿透(message filter)來讓某些消息通過:
1.添加P/Invoke包裝器到ChangeWindowMessageFilter本地函數之上,它使消息能穿透權 限級別。
2.在NativeWrappers類中添加如下代碼:
C#
public enum ChangeWindowMessageFilterFlags : uint {
Add = 1, Remove = 2
};
[DllImport("user32")]
public static extern bool ChangeWindowMessageFilter(uint msg,
ChangeWindowMessageFilterFlags flags);
幫助
當在表單構造器中成功注冊消息,用新添加的包裝器讓新注冊的消息可以通過而無不需考 慮權限級別:
3.添加對NativeWrappers.ChangeWindowMessageFilter的調用。修改其標記為 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);
}
4.編譯工程並使用ManagedPingPongLoader.exe進行測試。
如果一切順利程序此時應該可以正確工作。完整的解決方案在文件夾PingPongFixed中。
總結
本實驗中學習了如何使用Process Explorer診斷UIPI問題,並使得應用程序中的消息穿過 限制到達更高級別的權限。