1. 程式人生 > >系統關機重啟

系統關機重啟

  在列舉/結束系統程序或作業系統服務時,會出現許可權不足而失敗的情況,因此需要提升程序的許可權。

1 BOOL SystemRestart()
2 {
3     EnableXXXPrivilege(SE_SHUTDOWN_NAME);
4     return ExitWindowsEx(EWX_REBOOT, 0);
5 }

  windows的每個使用者登入系統後,系統會產生一個訪問令牌(access token),其中關聯了當前使用者的許可權資訊,使用者登入後建立的每一個程序都會有使用者access token的拷貝,當程序試圖執行某些需要特殊許可權的操作或是訪問受保護的核心物件,系統會檢查其access token的許可權資訊以決定是否授權操作。Administrator組成員的access token中會含有一些可以執行系統級操作的特權(privilege),如終止任意程序,關閉、重啟系統、載入裝置驅動和更改系統時間等,不過這些特權預設是被禁用的,當administrator組成員建立的程序中包含一些需要特權的操作時,程序必須首先開啟這些禁用的特權以提升自己的許可權,否則系統將拒絕程序的操作。注意,非administrator組成員建立的程序無法提升自身的許可權。
  Windows以字串的形式表示系統特權,如”SeCreatePagefilePrivilege”表示該特權用於建立頁面檔案,“SeDebugPrivilege”表示該特權可用於除錯及更改其他程序的記憶體。為了方便在程式碼中引用這些字串,微軟在winnt.h中定義了一組巨集,如#define SE_DEBUG_NAME TEXT(“SeDebugPrivilege”)。完整的特權列表可以查閱MSDN(Privilege Constants)一章。雖然Windows使用字串表示特權,但查詢或更改特權的API需要LUID來引用相應的特權,LUID表示local unique identifier,它是一個64位值,在當前系統中是唯一的。為了提升程序許可權到指定的特權,我們必須先找到該特權對應的LUID,這時要呼叫LookupPrivilegeValue函式。然後,我們需要呼叫AdjustTokenPrivileges函式,通知作業系統將指定的access token許可權中的特權置為開啟狀態。

 1 BOOL EnableXXXPrivilege( LPCTSTR pszPrivilegeName )
 2 {
 3     HANDLE hToken;
 4     LUID seXXXNameValue;    //本地唯一識別符號結構變數
 5     TOKEN_PRIVILEGES tkp;   //訪問令牌許可權結構變數
 6 
 7     //獲得程序訪問令牌的控制代碼
 8     if ( ! OpenProcessToken( GetCurrentProcess(),
 9         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
10 { 11 return FALSE; 12 } 13 14 //查詢SE_SHUTDOWN_NAME許可權所對應的luid值 15 //NULL:本地系統 pszPrivilegeName:SE_SHUTDOWN_NAME 16 if ( !LookupPrivilegeValue( NULL, pszPrivilegeName, &seXXXNameValue)) 17 { 18 CloseHandle( hToken ); 19 return FALSE; 20 } 21 22 //
填充Token_Privileges結構 23 tkp.PrivilegeCount = 1; 24 tkp.Privileges[0].Luid = seXXXNameValue; 25 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 26 27 //提升許可權 28 if ( !AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL )) 29 { 30 CloseHandle( hToken ); 31 return FALSE; 32 } 33 34 CloseHandle( hToken ); 35 36 return TRUE; 37 }

 


參考:https://blog.csdn.net/chenyonken/article/details/78290810