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為空,該參數
在Winnt.h中還定義了一些權限名稱的宏,如:
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*/) 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);
}