Untitled
unknown
plain_text
22 days ago
4.7 kB
3
Indexable
#include <stdio.h> #include <Windows.h> #include <sddl.h> #define MAX_NAME 256 /* * The API_CHECK_SUCCESS macro helps handling APIs which return FALSE on failure. * It just catch the case when the function fails, print a message and jumps to * the Cleanup label at the end of the function where resources are released. * Enclose API calls with the macro this way: * API_CHECK_SUCCESS( FunctionToCall(Arg1, Arg2, Arg3, ....) ); */ #define API_CHECK_SUCCESS(_CALL) \ do { \ if (FALSE == (_CALL)) { \ dwRet = GetLastError(); \ fprintf(stderr, "[%d] - %s failed with 0x%08x\n", __LINE__, #_CALL, dwRet); \ goto Cleanup; \ } \ } while (0) int main() { DWORD dwRet = 0; // Error code for our program HANDLE hMyToken; // Handle to the token HANDLE hThisProcess; // Handle to the process TOKEN_GROUPS* pTokenGroups; // TOKEN_GROUPS structure which receives groups list DWORD bufferSize = 0; // Size to allocate for GetTokenInformation WCHAR wszName[MAX_NAME]; // Temporary buffer to store the name part for the SID WCHAR wszDomain[MAX_NAME]; // Temporary buffer to store the domain part for the SID DWORD dwNameSize = 0; // Stores the size of the name in wszName DWORD dwDomainSize = 0; // Stores the size of the domain in wszDomain WCHAR* wszSID = NULL; // Points to a text representation of the SID SID_NAME_USE sidType; // SID type enum. // 1. Get a handle to the current process hThisProcess = GetCurrentProcess(); // 2. Open the process's token API_CHECK_SUCCESS(OpenProcessToken( hThisProcess, TOKEN_QUERY, &hMyToken)); /* * 3. Get the list of groups by calling GetTokenInformation * * 3.1 Get required memory size. * GetTokenInformation does not allocate memory for us. We need to allocate * a buffer. * Usual convention in Windows. We first call the API with a NULL argument * which is a convention for asking what is the required size for the area * which will contain information. */ GetTokenInformation( hMyToken, TokenGroups, nullptr, pTokenGroups, 0, &bufferSize); // 3.2 Allocate sufficent memory pTokenGroups = static_cast<TOKEN_GROUPS *>( malloc(bufferSize) ); if (nullptr == pTokenGroups) { fprintf(stderr, "malloc returns NULL\n"); dwRet = ENOMEM; goto Cleanup; } /* * 3.3 Call GetTokenInformation again * This time, specifying the memory buffer where to store data. */ API_CHECK_SUCCESS(GetTokenInformation( hMyToken, TokenGroups, pTokenGroups, bufferSize, &bufferSize)); // 4. Display group information. // Print a header in the console and loop over the groups wprintf(L"Groups for token %08X:\n", hMyToken); for (DWORD i = 0; i < pTokenGroups->GroupCount; ++i) { // 4.1 Get a text representation of the SID ConvertSidToStringSidW(pTokenGroups->Groups[i].Sid, &wszSID); // 4.2 Prepare temporary buffers to store the result of SID->name translation dwNameSize = MAX_NAME * sizeof(WCHAR); ZeroMemory(wszName, dwNameSize); dwDomainSize = MAX_NAME * sizeof(WCHAR); ZeroMemory(wszDomain, dwDomainSize); // 4.3 calls LookupAccountSidW to perform SID->name translation if (LookupAccountSidW( NULL, // Local computer pTokenGroups->Groups[i].Sid, wszName, &dwNameSize, wszDomain, &dwDomainSize, &sidType)) { // SID->name translation was successfull // 4.3a.1 Display group in the console if (wcsnlen_s(wszDomain, dwDomainSize) == 0) wprintf(L"[%02d] %s %s\n", i, wszName, wszSID); else wprintf(L"[%02d] %s\\%s %s\n", i, wszDomain, wszName, wszSID); } else { // SID->name translation failed // 4.3b.1 Just display the SID in the console wprintf(L"[%02d] %s\n", i, wszSID); } // 4.4 We need to free wszSID here LocalFree(wszSID); } Cleanup: // 5. Be polite and close the handle we opened to the token. CloseHandle(hMyToken); return 0; }
Editor is loading...
Leave a Comment