進程令牌(TOKEN)相關!

來源:互聯網
上載者:User

 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 AdjustTokenPrivileges(
HANDLE TokenHandle, // handle to token
BOOL DisableAllPrivileges, // disabling option
PTOKEN_PRIVILEGES NewState, // privilege information
DWORD BufferLength, // size of buffer
PTOKEN_PRIVILEGES PreviousState, // original state buffer
PDWORD ReturnLength // required buffer size
);
第一個參數是存取權杖的控制代碼;第二個參數決定是進行許可權修改還是除能(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, // system name
LPCTSTR lpName, // privilege name
PLUID lpLuid // locally unique identifier
);
第一個參數是系統的名稱,如果是本地系統只要指明為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)來打獲得任意進程的控制代碼,並且指定了所有的訪問權

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.