目標
本實驗中你將學到:
• 識別用戶界面隔離級別(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問題,並使得應用程序中的消息穿過 限制到達更高級別的權限。