GetTokenInformation 用於檢索進程或線程的令牌(Token)信息。Token是一個數據結構,其包含有關進程或線程的安全上下文,代表當前用戶或服務的安全標識符和許可權信息。GetTokenInformation函數也可以用來獲取這些安全信息,通常用於在運行時檢查某個進程或線程的許可權或安... ...
GetTokenInformation 用於檢索進程或線程的令牌(Token)信息。Token是一個數據結構,其包含有關進程或線程的安全上下文,代表當前用戶或服務的安全標識符和許可權信息。GetTokenInformation函數也可以用來獲取這些安全信息,通常用於在運行時檢查某個進程或線程的許可權或安全信息。
該函數原型如下:
BOOL GetTokenInformation(
HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
LPVOID TokenInformation,
DWORD TokenInformationLength,
PDWORD ReturnLength
);
參數說明:
- TokenHandle:當前進程或線程令牌的句柄。
- TokenInformationClass:表示要檢索的Token信息類別,是TOKEN_INFORMATION_CLASS枚舉類型的值之一。這個參數的值確定TokenInformation參數的方案,以及返回的信息類型。
- TokenInformation:指向要接收信息的緩衝區的指針。
- TokenInformationLength:要接收的緩衝區的大小(以位元組為單位)。
- ReturnLength:實際緩衝區的大小(以位元組為單位)。
常見的TokenInformationClass值包括:
- TokenUser:用戶標識信息;
- TokenGroups:組信息;
- TokenOwner:所有者信息;
- TokenPrimaryGroup:主組信息;
- TokenPrivileges:特權信息;
- TokenSessionId:會話ID信息。
該函數的返回值為BOOL類型。如果函數執行成功,則返回非零值,否則返回零。如果函數返回零,則可以調用 GetLastError() 函數獲取錯誤代碼。
#include <stdio.h>
#include <ShlObj.h>
#include <Windows.h>
void ShowPrviliges(HANDLE process)
{
// 通過進程句柄獲取到進程令牌
HANDLE hToken;
OpenProcessToken(process, TOKEN_QUERY, &hToken);
// 獲取查詢到的令牌信息
DWORD dwSize;
GetTokenInformation(hToken, TokenPrivileges, NULL, NULL, &dwSize);
// 根據令牌中的大小分配空間
char* pBuf = new char[dwSize] {};
GetTokenInformation(hToken, TokenPrivileges, pBuf, dwSize, &dwSize);
// 將記憶體中的內容用要查詢數據結構體解析
TOKEN_PRIVILEGES* pTp = (TOKEN_PRIVILEGES*)pBuf;
DWORD dwCount = pTp->PrivilegeCount; // 解析出許可權個數
LUID_AND_ATTRIBUTES* pluid = pTp->Privileges; // 具備的許可權類型
for (int i = 0; i < dwCount; i++, pluid++)
{
char szName[100] = {};
DWORD dwLen = sizeof(szName);
LookupPrivilegeNameA(0, &pluid->Luid, szName, &dwLen);
switch (pluid->Attributes)
{
case 0:
printf("ID => %3d \t 狀態 => 關閉 \t\t 類型 => %s \n", i, szName); break;
case 1:
printf("ID => %3d \t 狀態 => 預設 \t\t 類型 => %s \n", i, szName); break;
case 2:
printf("ID => %3d \t 狀態 => 開啟 \t\t 類型 => %s \n", i, szName); break;
case 3:
printf("ID => %3d \t 狀態 => 預設開啟 \t\t 類型 => %s \n", i, szName); break;
}
}
delete pBuf;
}
int main(int argc, char* argv[])
{
// 拿到自身程式的句柄
HANDLE LocalProcess = GetCurrentProcess();
ShowPrviliges(LocalProcess);
system("pause");
return 0;
}
如下所示代碼同樣是一段許可權檢索的實現,函數EnumOwner()
接受一個指向進程令牌的句柄,並使用它來檢索有關令牌用戶的信息。使用GetTokenInformation()
獲取一個包含令牌用戶的安全標識符(SID
)指針的TOKEN_USER
結構。然後,它使用LocalAlloc()
為SID
分配記憶體,並使用CopySid()
將SID
複製到該記憶體中。最後使用LookupAccountSid()
檢索與SID
相關聯的用戶賬戶的名稱。函數返回指向包含賬戶名稱的字元字元串的指針。
在main()
函數中使用OpenProcess()
和PROCESS_QUERY_INFORMATION
標誌檢索當前進程的句柄。然後,它使用OpenProcessToken()
和TOKEN_QUERY
標誌檢索進程令牌的句柄。將該句柄傳遞給EnumOwner()
以檢索與令牌相關聯的用戶賬戶名稱。最後使用printf()
列印賬戶名稱,使用CloseHandle()
關閉令牌句柄,使用CloseHandle()
關閉進程句柄。
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
// 通過進程Token獲取進程許可權類型
char * __stdcall EnumOwner(HANDLE htoken)
{
DWORD dwLen;
PSID pSid = 0;
TOKEN_USER* pWork;
SID_NAME_USE use;
TCHAR User[256], Domain[256];
GetTokenInformation(htoken, TokenUser, NULL, 0, &dwLen);
pWork = (TOKEN_USER*)LocalAlloc(LMEM_ZEROINIT, dwLen);
if (GetTokenInformation(htoken, TokenUser, pWork, dwLen, &dwLen))
{
dwLen = GetLengthSid(pWork->User.Sid);
pSid = (PSID)LocalAlloc(LMEM_ZEROINIT, dwLen);
CopySid(dwLen, pSid, pWork->User.Sid);
dwLen = 256;
LookupAccountSid(NULL, pSid, &User[0], &dwLen, &Domain[0], &dwLen, &use);
// printf("\t 主機 => %s \t 許可權用戶 => %s ", Domain, User);
return User;
}
return NULL;
}
int main(int argc, char* argv[])
{
HANDLE ProcessHandle, hToken;
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE,GetCurrentProcessId());
if (ProcessHandle != NULL)
{
if (OpenProcessToken(ProcessHandle, TOKEN_QUERY, &hToken))
{
char *token = EnumOwner(hToken);
printf("[+] 當前進程身份: %s \n", token);
CloseHandle(hToken);
CloseHandle(ProcessHandle);
}
}
system("pause");
return 0;
}
本文作者: 王瑞
本文鏈接: https://www.lyshark.com/post/136e2c9d.html
版權聲明: 本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
文章出處:https://www.cnblogs.com/LyShark/p/17723951.html
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!