程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> GetCurrentProcessID 得到當前進程的ID OpenProcessToken 得到進程的令牌句柄 LookupPrivilegeValue 查詢進程的權限

GetCurrentProcessID 得到當前進程的ID OpenProcessToken 得到進程的令牌句柄 LookupPrivilegeValue 查詢進程的權限

編輯:.NET實例教程

GetCurrentProcessID            得到當前進程的ID   
OpenProcessToken          得到進程的令牌句柄
LookupPrivilegeValue          查詢進程的權限
AdjustTokenPrivileges          判斷令牌權限  

            要對一個任意進程(包括系統安全進程和服務進程)進行指定了寫相關的訪問權的OpenProcess操作,只要當前進程具有SeDeDebug權限就可以了。要是一個用戶是Administrator或是被給予了相應的權限,就可以具有該權限。可是,就算我們用Administrator帳號對一個系統安全進程執行OpenProcess(PROCESS_ALL_Access,FALSE,          dwProcessID)還是會遇到“訪問拒絕”的錯誤。什麼原因呢?原來在默認的情況下進程的一些訪問權限是沒有被使能(Enabled)的,所以我們要做的首先是使能這些權限。與此相關的一些API函數有OpenProcessToken、LookupPrivilegevalue、AdjustTokenPrivileges。我們要修改一個進程的訪問令牌,首先要獲得進程訪問令牌的句柄,這可以通過OpenProcessToken得到,函數的原型如下:

BOOL      OpenProcessToken(
           HANDLE      ProcessHandle,       //要修改訪問權限的進程句柄
           DWord      DesiredAccess,        //指定你要進行的操作類型
           PHANDLE      TokenHandle         //返回的訪問令牌指針
     );

            第一參數是要修改訪問權限的進程句柄;第三個參數就是返回的訪問令牌指針;第二個參數指定你要進行的操作類型,如要修改令牌我們要指定第二個參數為TOKEN_ADJUST_PRIVILEGES(其它一些參數可參考Platform          SDK)。通過這個函數我們就可以得到當前進程的訪問令牌的句柄(指定函數的第一個參數為GetCurrentProcess()就可以了)。接著我們可以調用AdjustTokenPrivileges對這個訪問令牌進行修改。AdjustTokenPrivileges的原型如下:

BOOL AdjustTokenPrivi

leges(
      HANDLE TokenHandle,                        // 訪問令牌的句柄
      BOOL DisableAllPrivileges,                  // 決定是進行權限修改還是除能(Disable)所有權限
      PTOKEN_PRIVILEGES NewState,        // 指明要修改的權限,是一個指向TOKEN_PRIVILEGES結構
                                                                     的指針,該結構包含一個數組,數據組的每個項指明了權限
                                                                     的類型和要進行的操作;
      DWord BufferLength,                         //結構PreviousState的長度,如果PreviousState為空,該參數
                                                                     

應為NULL
      PTOKEN_PRIVILEGES PreviousState,  // 指向TOKEN_PRIVILEGES結構的指針,存放修改前的訪問
                                                                      權限的信息
      PDWord ReturnLength                      //實際PreviousState結構返回的大小
);

            第一個參數是訪問令牌的句柄;第二個參數決定是進行權限修改還是除能(Disable)所有權限;第三個參數指明要修改的權限,是一個指向TOKEN_PRIVILEGES結構的指針,該結構包含一個數組,數據組的每個項指明了權限的類型和要進行的操作;          第四個參數是結構PreviousState的長度,如果PreviousState為空,該參數應為NULL;第五個參數也是一個指向TOKEN_PRIVILEGES結構的指針,存放修改前的訪問權限的信息,可空;最後一個參數為實際PreviousState結構返回的大小。在使用這個函數前再看一下TOKEN_PRIVILEGES這個結構,其聲明如下:

typedef          struct          _TOKEN_PRIVILEGES          {   
         DWord          PrivilegeCount;   
         LUID_AND_ATTRIBUTES          Privileges[];   
}TOKEN_PRIVILEGES,          *PTOKEN_PRIVILEGES;   

            PrivilegeCount指的數組原素的個數,接著是一個LUID_AND_ATTRIBUTES類型的數組,再來看一下LUID_AND_ATTRIBUTES這個結構的內容,聲明如下:

typedef          struct          _LUID_AND_ATTRIBUTES          {   
           LUID              Luid;   
           DWord            Attributes;   
}LUID_AND_ATTRIBUTES,          *PLUID_AND_ATTRIBUTES

            第二個參數就指明了我們要進行的操作類型,有三個可選項:  
   
SE_PRIVILEGE_ENABLED
SE_PRIVILEGE_ENABLED_BY_DEFAULT
SE_PRIVILEGE_USED_FOR_Access

要使能一個權限就指定Attributes為SE_PRIVILEGE_ENABLED。第一個參數就是指權限的類型,是一個LUID的值,LUID就是指locally          unique          identifIEr,我想GUID大家是比較熟悉的,和GUID的要求保證全局唯一不同,LUID只要保證局部唯一,就是指在系統的每一次運行期間保證是唯一的就可以了。另外和GUID相同的一點,LUID也是一個64位的值,相信大家都看過GUID那一大串的值,我們要怎麼樣才能知道一個權限對應的LUID值是多少呢?這就要用到另外一個API函數LookupPrivilegevalue,其原形如下:

BOOL LookupPrivilegeValue(
      LPCTSTR lpSystemName,     //系統的名稱,若為空,則在當前的sysytem查找。
      LPCTSTR lpName,                // 指明了權限的名稱,如“SeDebugPrivilege”。
      PLUID lpLuid                          // 返回LUID的指針
);

            第一個參數是系統的名稱,如果是本地系統只要指明為NULL就可以了,第三個參數就是返回LUID的指針,第二個參數就是指明了權限的名稱,如“SeDebugPrivilege”。

在Winnt.h中還定義了一些權限名稱的宏,如:

#define          SE_BACKUP_NAME                        TEXT("SeBackupPrivilege")
#define          SE_RESTORE_NAME                     TEXT("SeRestorePrivilege")
#define          SE_SHUTDOWN_NAME                  TEXT("SeShutdownPrivilege")
#define          SE_DEBUG_NAME                          TEXT("SeDebugPrivilege")

這樣通過這三個函數的調用,我們就可以用OpenProcess(PROCESS_ALL_Access,FALSE,          dwProcessID)來打獲得任意進程的句柄,並且指定了所有的訪問權。

 

pszPrivName:

#define          SE_BACKUP_NAME                        TEXT("SeBackupPrivilege")
#define          SE_RESTORE_NAME                     TEXT("SeRestorePrivilege")
#define          SE_SHUTDOWN_NAME                  TEXT("SeShutdownPrivilege")
#define          SE_DEBUG_NAME                          TEXT("SeDebugPrivilege")

BOOL EnablePrivilege(LPCTSTR pszPrivName,

BOOL fEnable /*= TRUE*/)
{   
 BOOL fOk = FALSE;   
 // Assume function fails   
 HANDLE hToken;   
 // Try to open this process's Access token   
 if (OpenProcessToken(GetCurrentProcess(),   
     TOKEN_ADJUST_PRIVILEGES, &hToken))  
 {       
  // privilege       
  TOKEN_PRIVILEGES tp = { 1 };       

  if( LookupPrivilegeValue(NULL, pszPrivName,  &tp.Privileges[0].Luid) )
  {
   tp.Privileges[0].Attributes = fEnable ?  SE_PRIVILEGE_ENABLED : 0;

   AdjustTokenPrivileges(hToken, FALSE, &tp,         
         sizeof(tp), NULL, NULL);

   fOk = (GetLastError() == ERROR_SUCCESS);  
  }
  CloseHandle(hToken); 
 } 
 return(fOk);
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved