網上關于這個問題討論較多,但也不外乎幾種方法??偨Y一下,如附中。順便了解一個UAC。 

UAC,全稱User Account Control(用戶帳戶控制) 

System Safe Monitor(主機入侵防御系統)

UAC是如何工作的[3]

我們可以簡單的把UAC當作權限臨時重分配的工具。在默認情況下,所有的非系統核心進程都只擁有標準權限,這一權限不能對系統關鍵區域進行修改。對于一個程序,如果它當中含有提權申請,則在運行時會彈出UAC窗口要求提權。如果用戶允許,則程序暫時性的獲得了最高權限,可以對系統關鍵區域進行更改;如果用戶拒絕,則程序被拒絕執行。而如果程序中沒有提權申請,則系統會讓程序運行于標準權限下。同時,對于所有程序,都可以用“以管理員身份運行”的方式手動提權。而即便病毒感染了系統,它也處于UAC的監視之下,這使得病毒的反清除行為會受到很大阻礙。正是憑借這一機制,UAC成為了一道重要的系統防火墻。

在 Windows7(NT6.x系統)中,系統取消了對移動設備Autorun.inf的支持

用戶界面特權隔離[5]

在早期的Windows操作系統中,在同一用戶下運行的所有進程有著相同的安全等級,擁有相同的權限。例如,一個進程可以自由地發送一個Windows消息到另外一個進程的窗口。從Windows Vista開始,當然也包括Windows 7,對于某些Windows消息,這一方式再也行不通了。進程(或者其他的對象)開始擁有一個新的屬性——特權等級(Privilege Level)。一個特權等級較低的進程不再可以向一個特權等級較高的進程發送消息,雖然他們在相同的用戶權限下運行。這就是所謂的用戶界面特權隔離 (User Interface Privilege Isolation,UIPI)。

UIPI的引入,最大的目的是防止惡意代碼發送消息給那些擁有較高權限的窗口以對其進行攻擊,從而獲取較高的權限等等。

UIPI的運行機制

在Windows 7中,當UAC(User Account Control)啟用的時候,UIPI的運行可以得到最明顯的體現。在UAC中,當一個管理員用戶登錄系統后,操作系統會創建兩個令牌對象(Token Object):第一個是管理員令牌,擁有大多數特權(類似于Windows Vista之前的System中的用戶),而第二個是一個經過過濾后的簡化版本,只擁有普通用戶的權限。

默認情況下,以普通用戶權限啟動的進程擁有普通特權等級(UIPI的等級劃分為低等級(low),普通(normal),高等級(high),系統 (system))。同樣的,以管理員權限運行的進程,例如,用戶右鍵單擊選擇“以管理員身份運行”或者是通過添加“runas”參數調用 ShellExecute運行的進程,這樣的進程就相應地擁有一個較高(high)的特權等級。

這將導致系統會運行兩種不同類型,不同特權等級的進程(當然,從技術上講這兩個進程都是在同一用戶下)。我們可以使用Windows Sysinternals工具集中的進程瀏覽器(Process Explorer)查看各個進程的特權等級。[6]

所以,當你發現你的進程之間Windows消息通信發生問題時,不妨使用進程瀏覽器查看一下兩個進程之間是否有合適的特權等級。

UIPI所帶來的限制

正如我們前文所說,等級的劃分,是為了防止以下犯上。所以,有了用戶界面特權隔離,一個運行在較低特權等級的應用程序的行為就受到了諸多限制,它不可以:

?驗證由較高特權等級進程創建的窗口句柄

?通過調用SendMessage和PostMessage向由較高特權等級進程創建的窗口?發送Windows消息

?使用線程鉤子處理較高特權等級進程

?使用普通鉤子(SetWindowsHookEx)監視較高特權等級進程

?向一個較高特權等級進程執行DLL注入

但是,一些特殊Windows消息是容許的。因為這些消息對進程的安全性沒有太大影響。這些Windows消息包括:

0x000 - WM_NULL

0x003 - WM_MOVE

0x005 - WM_SIZE

0x00D - WM_GETTEXT

0x00E - WM_GETTEXTLENGTH

0x033 - WM_GETHOTKEY

0x07F - WM_GETICON

0x305 - WM_RENDERFORMAT

0x308 - WM_DRAWCLIPBOARD

0x30D - WM_CHANGECBCHAIN

0x31A - WM_THEMECHANGED

0x313, 0x31B (WM_???)

修復UIPI問題

基于Windows Vista之前的操作系統行為所設計的應用程序,可能希望Windows消息能夠在進程之間自由的傳遞,以完成一些特殊的工作。當這些應用程序在 Windows 7上運行時,因為UIPI機制,這種消息傳遞被阻斷了,應用程序就會遇到兼容性問題。為了解決這個問題,Windows Vista引入了一個新的API函數ChangeWindowMessageFilter[7]。利用這個函數,我們可以添加或者刪除能夠通過特權等級隔離的 Windows消息。這就像擁有較高特權等級的進程,設置了一個過濾器,允許通過的Windows消息都被添加到這個過濾器的白名單,只有在這個白名單上的消息才允許傳遞進來。

如果我們想容許一個消息可以發送給較高特權等級的進程,我們可以在較高特權等級的進程中調用ChangeWindowMessageFilter函數,以 MSGFLT_ADD作為參數將消息添加進消息過濾器的白名單。同樣的,我們也可以以MSGFLT_REMOVE作為參數將這個消息從白名單中刪除。

一個示例

對于系統消息的處理,接受消息的進程需要將該消息加入到白名單中,可以通過下面的代碼實現:

需要在高權限程序開始的地方加入以下代碼,指定什么消息可以接受

 

代碼
1 typedef BOOL (WINAPI *_ChangeWindowMessageFilter)( UINT , DWORD);
2
3 BOOL CVistaMsgRecvApp::AllowMeesageForVista(UINT uMessageID, BOOL bAllow)//注冊Vista全局消息
4  {
5 BOOL bResult = FALSE;
6 HMODULE hUserMod = NULL;
7  //vista and later
8 hUserMod = LoadLibrary( L"user32.dll" );
9 if( NULL == hUserMod )
10 {
11 return FALSE;
12 }
13 _ChangeWindowMessageFilter pChangeWindowMessageFilter = (_ChangeWindowMessageFilter)GetProcAddress( hUserMod, "ChangeWindowMessageFilter" );
14 if( NULL == pChangeWindowMessageFilter )
15 {
16 AfxMessageBox(_T("create windowmessage filter failed"));
17 return FALSE;
18 }
19 bResult = pChangeWindowMessageFilter( uMessageID, bAllow ? 1 : 2 );//MSGFLT_ADD: 1, MSGFLT_REMOVE: 2
20 if( NULL != hUserMod )
21 {
22 FreeLibrary( hUserMod );
23 }
24 return bResult;
25 }
對于自定義消息,通常是指大于WM_USER的消息,我們首先必須在系統中注冊該消息,然后在調用上面的代碼:

 

1 #define WM_MYNEWMESSAGE (WM_USER + 999)<BR>UINT uMsgBall=::RegisterWindowMessage (WM_MYNEWMESSAGE )<BR>if(!uMsgBall)<BR>return FALSE;<BR>
注冊消息通過RegisterWindowMessage實現,函數的參數就是你需要注冊的消息值。

 

此時,低等級的進程就可以像高等級的進程發送消息了。

附 Win7下如何讓應用程序以管理員身份進行安裝執行

1、法一:

runas /profile /env /user:mydomain\admin "mmc %windir%\system32\dsa.msc"

我感覺這種方法不靠譜。

2、法二:

通過manifest文件使VC應用程序獲得管理員權限

這種方法還不錯[1]。

<security>

<requestedPrivileges>

<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>

</requestedPrivileges>

</security>

3、法三:

起名為setup,win7會自己提升權限,增加manifest文件。還有一種方法是改注冊表。HKEY_CURRENT_USER\Software \Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

添加一個字符串值 名稱就是你的程序的路徑和名字,值為RUNASADMIN。

也可以做成服務。

4、其它方法:

還有的網友說:有個開源的項目叫做RunAs,就是用來以指定用戶來運行程序的項目,可以參考

參考網址和更多閱讀

[1] http://hi.baidu.com/crowreturns/blog/item/f5e7cefd7546a284b801a07e.html

[2] http://www.cnblogs.com/sun8134/archive/2009/10/30/1593025.html

[3] 360 論壇

[4] http://topic.csdn.net/u/20100203/14/d98d8310-4971-47d1-94b1-9cdfbf159b4f.html

[5] http://blog.csdn.net/jinhill/archive/2010/07/21/5752870.aspx

[6] Sysinternals Utilities Index

http://technet.microsoft.com/en-us/sysinternals/bb545027.aspx

[7] ChangeWindowMessageFilter

http://msdn.microsoft.com/en-us/library/ms632675%28VS.85%29.aspx

[ Using the ChangeWindowMessageFilter function is not recommended, as it has process-wide scope. Instead, use the ChangeWindowMessageFilterEx function to control access to specific windows as needed. ChangeWindowMessageFilter may not be supported in future versions of Windows.]

[8]http://it.chinawin.net/softwaredev/article-b6f9.html