Untitled
unknown
plain_text
9 months ago
4.7 kB
10
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