Vista 引進了比較嚴謹的程式存取限制, 這導致在 Vista 下的使用者必須強迫使用 “管理者身份” 執行我的程式.
我不希望這樣, 所以就有了下面的文章.
本文內容包含
1. Kenny Kerr 的文章: UAC 原理 (重點整理)
* 系統提醒使用者是否需要系統管理者權限執行的流程
* 如果不論程式的相容性與 manifest 如何,
我就是要 elevation 我的程式, 該怎麼做?
* 如何知道我現在的執行權限是不是 elevation?
2. Understanding and Working in Protected Mode Internet Explorer
重點整理
* 如何知道目前我的程式是否處於 IE 的 Protected Mode?
* 那檢測結果確實發現我的 ocx 在 IE 的 Protected Mode 下,
那我該怎麼存取我的設定檔?
* 可是我就是要把資料存到 User Profile 怎麼辦?
* Michael Dunn 提供的程式範例 [3]
開始!
Kenny Kerr 先生在 2006 年9 月發表了一篇有關 Vista User Account Control 的精彩文章.
Windows Vista for Developers – Part 4 – User Account Control
內容包含
- 介紹如何使用 CreateRestrictedToken 建立一個 Token
- 詳細解說 Vista 新功能 User Account Control 對程式的影響與運作機制
- 介紹如何建立一個 Token, 使得擁有該 token 的程式不能 restart, sleep, shutdown 你的電腦
* 利用剛剛建立的 token 讓你的電腦完全不能關機
(藉由修改 Explore.exe 的執行權限)
如何讓公共的電腦限制執行權限 ? 我想答案應該在這裡吧.
4. 你可以指定 child process 的 integrity levels (我翻譯成執行層級, 比較好理解)
5. 他提供了一個例子, 讓 notepad.exe 只能開檔但是不能存檔.
VERIFY(::CreateProcessAsUser(duplicateToken,
L"C:\\Windows\\Notepad.exe",
0, // cmd line
0, // process attributes
0, // thread attributes
FALSE, // don't inherit handles
0, // flags
0, // inherit environment
0, // inherit current directory
&startupInfo,
&processInfo));
其他的重點摘要:
* 一般程式執行層級是 Medium, 而經過使用者允許過後的程式 token 執行層級是 High. 注意: IE 的 token 執行層級是 Low
* 你可以用 Mark 先生發表的軟体 Process Explorer 中, 看到每個 process
的執行權限層級 (開啟 integrity level 選項).
* 我們可以用 GetTokenInformation 得知目前 process 的 integrity level (順便驗證一下你的 ocx 在 IE 7 下的 integrity level是不是 Low)
系統提醒使用者是否需要系統管理者權限執行的流程
Step 1: 當使用者點選需要系統管理需求的程式執行時
Step 2: ShellExecute 呼叫 CreateProcess 建立新的 process, 隨後
CreateProcess 接手檢查這個 process 的相容性等工作
Step 3: 若發現需要 elevation(系統管理者權限), 而呼叫的人沒有elevation
則 CreateProcess 回傳 ERROR_ELEVATION_REQUIRED
Step 4: ShellExecute 發現這種狀況, 則交給 Application Information
Service 處理顯示提示視窗, 並且執行該需要 elevation 的程式.
如果不論程式的相容性與 manifest 如何, 我就要 elevation 我的程式的作法
<sol> 使用 runas 指令 (XP 就有這個指令了)
範例:
::ShellExecute(0, // owner window
L"runas",
L"C:\\Windows\\Notepad.exe",
0, // params
0, // directory
SW_SHOWNORMAL);
如何知道我現在的執行權限是不是 elevation?
<sol> 呼叫 IsUserAnAdmin 即可
另外下面是 “Understanding and Working in Protected Mode Internet Explorer” [2] 的重點整理
1. 如何知道目前我的程式是否處於 IE 的 Protected Mode?
<sol> 呼叫 IEIsProtectedModeProcess
那檢測結果確實發現我的 ocx 在 IE 的 Protected Mode 下, 那我該怎麼存取我的設定檔? (LocalLow)
<sol> 當你程式被執行在 IE Protected Mode (low integrity level), 那麼你的 ocx 可以寫入 %userprofile%\AppData\LocalLow 目錄下面. 利用 SHGetKnownFolderPath 搭配 FOLDERID_LocalAppDataLow 可以取得這個目錄的位置. (注意: 這段是 Vista 相關, 所以你的 ocx 必須要判斷作業系統而決定呼叫)
程式碼範例:
SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0,
NULL, szPath, ARRAYSIZE(szPath));
我們可以用上面的知識, 得知 low integrity level 的 process 可以自由存取放在 LocalLow 中的內容.
可是我就是要把資料存到 User Profile 怎麼辦?
<sol> 這個情況大多是你的 ocx 紀錄使用者設定檔資料.
詳細的作法如下 (3 steps): 會跳出視窗提醒使用者
Step 1: 先在 LocalLow 裡面建立你的設定檔
(用 IEGetWriteableFolderPath )
Step 2: 呼叫 IEShowSaveFileDialog, 這個 function 是用 medium
integrity context 中執行, 會提醒使用者我們要存東西到其
他目錄.
Step 3: 然後用 IESaveFile 把你的檔案放過去.
Michal Dunn 文章 [3] 在他的文章也列出使用範例
// Step 1: 取出 Protected Mode 情況下可以存取的目錄
先把東西存過去
LPWSTR pwszCacheDir = NULL;// 暫存空間目錄
TCHAR szTempFile[MAX_PATH] = {0};//暫存空間中完整檔案路徑
hr = IEGetWriteableFolderPath (FOLDERID_InternetCache,
&pwszCacheDir );
if(S_OK !=hr) return FALSE;
// 在 cache 目錄中建立暫存檔, 放我們的設定檔
GetTempFileName ( CW2CT(pwszCacheDir), _T("bob"),
0, szTempFile );
CoTaskMemFree ( pwszCacheDir );
// 然後存檔到暫存空間 (szTempFile) …
// Step 2: 跳出視窗, 由使用者選擇目標目錄.
HRESULT hr;
HANDLE hState;
LPWSTR pwszSelectedFilename = NULL;
const DWORD dwSaveFlags =
OFN_ENABLESIZING | OFN_HIDEREADONLY |
OFN_PATHMUSTEXIST |OFN_OVERWRITEPROMPT;
hr = IEShowSaveFileDialog (
m_hWnd, L"Saved log.txt", NULL,
L"Text files|*.txt|All files|*.*|",
L"txt", 1, dwSaveFlags, &pwszSelectedFilename,
&hState );
if ( S_OK != hr )
MessageBox(_T("IEShowSaveFileDialog 出問題”));
// Step 3: 最後用 IESave 存到目標目錄
hr = IESaveFile ( hState, T2CW(szTempFile) );
if(S_OK!=hr)
IECancelSaveFile ( hState );//出問題,取消存檔
else
DeleteFile ( szTempFile ); // 清除在 cache 中的暫存檔
如果我的 ocx 會呼叫其他執行檔工作, 該怎麼辦?
<sol> 告訴 IE 你要執行的 EXE 是可以信任的並且不要彈出視窗.
作法是: 在
HKLM\Software\Microsoft\Internet Explorer\Low Rights\ElevationPolicy下面, 建立一個新的 key. 並且包含 3 項資料.
AppName: 你的執行檔名稱. (例如: abc.exe)
AppPath: 執行檔位置
Policy: 這裡設定為 3
其他細節, 請參考延伸閱讀中他們的文章.
by Jing.
延伸閱讀
[1] M. Russinovich, “Inside Windows Vista User Account Control, “ http://technet.microsoft.com/en-us/magazine/2007.06.uac.aspx, 2007,7.
[2] M. Silbey and P. Brundrett, “Understanding and Working in Protected Mode Internet Explorer, “ http://msdn.microsoft.com/en-us/library/bb250462.aspx#wpm_fliwl, 2009, 2.
[3] M. Dunn, “A Developer's Survival Guide to IE Protected Mode, “ http://www.codeproject.com/KB/vista-security/PMSurvivalGuide.aspx, 2007, 5.
版大您好~
回覆刪除請教如何開啟 integrity level 選項呢?
是select columns->process Image-> integrity level 這個選項嗎???
但不知為何~ 這選項被disable(它是灰色的)不能勾選!!
或是有其他方式開啟integrity level
懇請不吝賜教! 謝謝