mirror of
https://github.com/pathtofile/SealighterTI
synced 2026-06-06 16:34:29 +00:00
675 lines
15 KiB
C++
675 lines
15 KiB
C++
#include "utils.h"
|
|
|
|
BOOL ParseArguments(int argc, wchar_t* argv[])
|
|
{
|
|
BOOL bReturnValue = TRUE;
|
|
BOOL bHelp = FALSE;
|
|
|
|
// Parse options
|
|
while ((argc > 1) && (argv[1][0] == '-'))
|
|
{
|
|
switch (argv[1][1])
|
|
{
|
|
case 'h':
|
|
bReturnValue = FALSE;
|
|
bHelp = TRUE;
|
|
break;
|
|
case 'v':
|
|
g_bVerbose = TRUE;
|
|
break;
|
|
case 'd':
|
|
g_bVerbose = TRUE;
|
|
g_bDebug = TRUE;
|
|
break;
|
|
case 'f':
|
|
g_bForce = TRUE;
|
|
break;
|
|
default:
|
|
wprintf(L"[-] Invalid option: %ws\n", argv[1]);
|
|
bReturnValue = FALSE;
|
|
}
|
|
++argv;
|
|
--argc;
|
|
}
|
|
|
|
if (bHelp)
|
|
{
|
|
PrintUsage();
|
|
return FALSE;
|
|
}
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
VOID PrintArguments()
|
|
{
|
|
PrintVerbose(L"Verbose=%d | Debug=%d | Force=%d", g_bVerbose, g_bDebug, g_bForce);
|
|
}
|
|
|
|
VOID PrintUsage()
|
|
{
|
|
wprintf(
|
|
L" ___ ___ \n"
|
|
" (o o) (o o) \n"
|
|
"( V ) Sealighter TI ( V ) version %ws\n"
|
|
"--m-m-------------------m-m-- by %ws\n"
|
|
" (Original PPLDump by %ws)\n"
|
|
"Description:\n"
|
|
" Inject into a PPL Process and Start an ETW Trace for the\n"
|
|
" Microsoft-Windows-Threat-Intelligence Provider\n"
|
|
"\n",
|
|
VERSION,
|
|
AUTHOR,
|
|
AUTHOR_ORIG
|
|
);
|
|
|
|
wprintf(
|
|
L"Usage: \n"
|
|
" SealighterTI.exe [-v] [-d] [-f]\n"
|
|
"\n"
|
|
);
|
|
|
|
wprintf(
|
|
L"Options:\n"
|
|
" -v (Verbose) Enable verbose mode\n"
|
|
" -d (Debug) Enable debug mode (implies verbose)\n"
|
|
" -f (Force) Bypass DefineDosDevice error check\n"
|
|
"\n"
|
|
);
|
|
|
|
wprintf(
|
|
L"Examples:\n"
|
|
" SealighterTI.exe\n"
|
|
" SealighterTI.exe -v -f\n"
|
|
);
|
|
}
|
|
|
|
VOID PrintLastError(LPCWSTR pwszFunctionName)
|
|
{
|
|
DWORD dwLastError = GetLastError();
|
|
wprintf(L"[-] %ws failed with error code %d - %ws\n", pwszFunctionName, dwLastError, _com_error(HRESULT_FROM_WIN32(dwLastError)).ErrorMessage());
|
|
}
|
|
|
|
VOID PrintVerbose(LPCWSTR pwszFormat, ...)
|
|
{
|
|
if (g_bVerbose)
|
|
{
|
|
LPWSTR pwszVerboseString = NULL;
|
|
DWORD dwVerboseStringLen = 0;
|
|
va_list va;
|
|
size_t st_Offset = 0;
|
|
WCHAR wszUsername[UNLEN + 1] = { 0 };
|
|
DWORD dwUsernameLen = UNLEN;
|
|
|
|
GetUserName(wszUsername, &dwUsernameLen);
|
|
|
|
va_start(va, pwszFormat);
|
|
if (g_bDebug)
|
|
dwVerboseStringLen += _scwprintf(L"[%ws] ", wszUsername) * sizeof(WCHAR);
|
|
|
|
dwVerboseStringLen += _vscwprintf(pwszFormat, va) * sizeof(WCHAR) + 2;
|
|
pwszVerboseString = (LPWSTR)LocalAlloc(LPTR, dwVerboseStringLen);
|
|
|
|
if (pwszVerboseString)
|
|
{
|
|
if (g_bDebug)
|
|
StringCbPrintf(pwszVerboseString, dwVerboseStringLen, L"[%ws] ", wszUsername);
|
|
|
|
if (SUCCEEDED(StringCbLength(pwszVerboseString, dwVerboseStringLen, &st_Offset)))
|
|
{
|
|
StringCbVPrintf(&pwszVerboseString[st_Offset / sizeof(WCHAR)], dwVerboseStringLen - st_Offset, pwszFormat, va);
|
|
|
|
wprintf(L"%ws", pwszVerboseString);
|
|
}
|
|
|
|
LocalFree(pwszVerboseString);
|
|
}
|
|
|
|
va_end(va);
|
|
}
|
|
}
|
|
|
|
VOID PrintDebug(LPCWSTR pwszFormat, ...)
|
|
{
|
|
if (g_bDebug)
|
|
{
|
|
LPWSTR pwszDebugString = NULL;
|
|
DWORD dwDebugStringLen = 0;
|
|
va_list va;
|
|
size_t st_Offset = 0;
|
|
WCHAR wszUsername[UNLEN + 1] = { 0 };
|
|
DWORD dwUsernameLen = UNLEN;
|
|
|
|
GetUserName(wszUsername, &dwUsernameLen);
|
|
|
|
va_start(va, pwszFormat);
|
|
dwDebugStringLen += _scwprintf(L"[DEBUG][%ws] ", wszUsername) * sizeof(WCHAR);
|
|
dwDebugStringLen += _vscwprintf(pwszFormat, va) * sizeof(WCHAR) + 2;
|
|
pwszDebugString = (LPWSTR)LocalAlloc(LPTR, dwDebugStringLen);
|
|
|
|
if (pwszDebugString)
|
|
{
|
|
StringCbPrintf(pwszDebugString, dwDebugStringLen, L"[DEBUG][%ws] ", wszUsername);
|
|
|
|
if (SUCCEEDED(StringCbLength(pwszDebugString, dwDebugStringLen, &st_Offset)))
|
|
{
|
|
StringCbVPrintf(&pwszDebugString[st_Offset / sizeof(WCHAR)], dwDebugStringLen - st_Offset, pwszFormat, va);
|
|
|
|
wprintf(L"%ws", pwszDebugString);
|
|
}
|
|
|
|
LocalFree(pwszDebugString);
|
|
}
|
|
|
|
va_end(va);
|
|
}
|
|
}
|
|
|
|
BOOL ProcessGetProtectionLevel(DWORD dwProcessId, PDWORD pdwProtectionLevel)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
|
|
HANDLE hProcess = NULL;
|
|
PROCESS_PROTECTION_LEVEL_INFORMATION level = { 0 };
|
|
|
|
if (!(hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId)))
|
|
{
|
|
PrintLastError(L"OpenProcess");
|
|
goto end;
|
|
}
|
|
|
|
if (!GetProcessInformation(hProcess, ProcessProtectionLevelInfo, &level, sizeof(level)))
|
|
{
|
|
PrintLastError(L"GetProcessInformation");
|
|
goto end;
|
|
}
|
|
|
|
*pdwProtectionLevel = level.ProtectionLevel;
|
|
bReturnValue = TRUE;
|
|
|
|
end:
|
|
if (hProcess)
|
|
CloseHandle(hProcess);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL ProcessGetProtectionLevelAsString(DWORD dwProcessId, LPWSTR* ppwszProtectionLevel)
|
|
{
|
|
BOOL bReturnValue = TRUE;
|
|
|
|
DWORD dwProtectionLevel = 0;
|
|
LPCWSTR pwszProtectionName = NULL;
|
|
|
|
if (!ProcessGetProtectionLevel(dwProcessId, &dwProtectionLevel))
|
|
return FALSE;
|
|
|
|
*ppwszProtectionLevel = (LPWSTR)LocalAlloc(LPTR, 64 * sizeof(WCHAR));
|
|
if (!*ppwszProtectionLevel)
|
|
return FALSE;
|
|
|
|
switch (dwProtectionLevel)
|
|
{
|
|
case PROTECTION_LEVEL_WINTCB_LIGHT:
|
|
pwszProtectionName = L"PsProtectedSignerWinTcb-Light";
|
|
break;
|
|
case PROTECTION_LEVEL_WINDOWS:
|
|
pwszProtectionName = L"PsProtectedSignerWindows";
|
|
break;
|
|
case PROTECTION_LEVEL_WINDOWS_LIGHT:
|
|
pwszProtectionName = L"PsProtectedSignerWindows-Light";
|
|
break;
|
|
case PROTECTION_LEVEL_ANTIMALWARE_LIGHT:
|
|
pwszProtectionName = L"PsProtectedSignerAntimalware-Light";
|
|
break;
|
|
case PROTECTION_LEVEL_LSA_LIGHT:
|
|
pwszProtectionName = L"PsProtectedSignerLsa-Light";
|
|
break;
|
|
case PROTECTION_LEVEL_WINTCB:
|
|
pwszProtectionName = L"PsProtectedSignerWinTcb";
|
|
break;
|
|
case PROTECTION_LEVEL_CODEGEN_LIGHT:
|
|
pwszProtectionName = L"PsProtectedSignerCodegen-Light";
|
|
break;
|
|
case PROTECTION_LEVEL_AUTHENTICODE:
|
|
pwszProtectionName = L"PsProtectedSignerAuthenticode";
|
|
break;
|
|
case PROTECTION_LEVEL_PPL_APP:
|
|
pwszProtectionName = L"PsProtectedSignerPplApp";
|
|
break;
|
|
case PROTECTION_LEVEL_NONE:
|
|
pwszProtectionName = L"None";
|
|
break;
|
|
default:
|
|
pwszProtectionName = L"Unknown";
|
|
bReturnValue = FALSE;
|
|
}
|
|
|
|
StringCchPrintf(*ppwszProtectionLevel, 64, L"%ws", pwszProtectionName);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL ProcessGetIntegrityLevel(DWORD dwProcessId, PDWORD pdwIntegrityLevel)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
|
|
HANDLE hProcess = NULL;
|
|
HANDLE hProcessToken = NULL;
|
|
PTOKEN_MANDATORY_LABEL pLabel = NULL;
|
|
DWORD dwLength = 0;
|
|
DWORD dwIntegrityLevel = 0;
|
|
|
|
if (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId)))
|
|
goto end;
|
|
|
|
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
|
|
goto end;
|
|
|
|
GetTokenInformation(hProcessToken, TokenIntegrityLevel, pLabel, dwLength, &dwLength);
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
goto end;
|
|
|
|
pLabel = (PTOKEN_MANDATORY_LABEL)LocalAlloc(LPTR, dwLength);
|
|
if (!pLabel)
|
|
goto end;
|
|
|
|
if (!GetTokenInformation(hProcessToken, TokenIntegrityLevel, pLabel, dwLength, &dwLength))
|
|
goto end;
|
|
|
|
dwIntegrityLevel = *GetSidSubAuthority(pLabel->Label.Sid, *GetSidSubAuthorityCount(pLabel->Label.Sid) - 1);
|
|
*pdwIntegrityLevel = dwIntegrityLevel;
|
|
bReturnValue = TRUE;
|
|
|
|
end:
|
|
if (pLabel)
|
|
LocalFree(pLabel);
|
|
if (hProcessToken)
|
|
CloseHandle(hProcessToken);
|
|
if (hProcess)
|
|
CloseHandle(hProcess);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL ProcessGetPIDFromName(LPWSTR pwszProcessName, PDWORD pdwProcessId)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
|
|
HANDLE hProcessSnap = NULL;
|
|
PROCESSENTRY32 pe32 = { 0 };
|
|
DWORD dwProcessId = 0;
|
|
DWORD dwMatchCount = 0;
|
|
BOOL bMatch = FALSE;
|
|
|
|
if ((hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)
|
|
{
|
|
PrintLastError(L"CreateToolhelp32Snapshot");
|
|
goto end;
|
|
}
|
|
|
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
|
if (!Process32First(hProcessSnap, &pe32))
|
|
{
|
|
PrintLastError(L"Process32First");
|
|
goto end;
|
|
}
|
|
|
|
do
|
|
{
|
|
bMatch = FALSE;
|
|
|
|
if (_wcsicmp(pe32.szExeFile, pwszProcessName) == 0)
|
|
bMatch = TRUE;
|
|
else
|
|
{
|
|
if (PathCchRemoveExtension(pe32.szExeFile, wcslen(pe32.szExeFile) + 1) == S_OK)
|
|
{
|
|
if (_wcsicmp(pe32.szExeFile, pwszProcessName) == 0)
|
|
bMatch = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bMatch)
|
|
{
|
|
dwProcessId = pe32.th32ProcessID;
|
|
dwMatchCount++;
|
|
}
|
|
|
|
} while (Process32Next(hProcessSnap, &pe32));
|
|
|
|
if (dwMatchCount == 0)
|
|
{
|
|
wprintf(L"[-] Failed to find a process that matches the provided name.\n");
|
|
goto end;
|
|
}
|
|
|
|
if (dwMatchCount > 1)
|
|
{
|
|
wprintf(L"[-] Found more than one process that matches the provided name. Please provide a PID instead.\n");
|
|
goto end;
|
|
}
|
|
|
|
*pdwProcessId = dwProcessId;
|
|
bReturnValue = TRUE;
|
|
|
|
end:
|
|
if (hProcessSnap)
|
|
CloseHandle(hProcessSnap);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
HANDLE ObjectManagerCreateDirectory(LPCWSTR dirname)
|
|
{
|
|
OBJECT_ATTRIBUTES oa = { 0 };
|
|
UNICODE_STRING name = { 0 };
|
|
HANDLE hDirectory = NULL;
|
|
NTSTATUS status = 0;
|
|
|
|
RtlInitUnicodeString(&name, dirname);
|
|
InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
|
|
|
status = NtCreateDirectoryObjectEx(&hDirectory, DIRECTORY_ALL_ACCESS, &oa, NULL, FALSE);
|
|
SetLastError(RtlNtStatusToDosError(status));
|
|
if (status != 0)
|
|
{
|
|
PrintLastError(L"NtCreateDirectoryObjectEx");
|
|
return NULL;
|
|
}
|
|
|
|
return hDirectory;
|
|
}
|
|
|
|
HANDLE ObjectManagerCreateSymlink(LPCWSTR linkname, LPCWSTR targetname)
|
|
{
|
|
OBJECT_ATTRIBUTES oa = { 0 };
|
|
UNICODE_STRING name = { 0 };
|
|
UNICODE_STRING target = { 0 };
|
|
HANDLE hLink = NULL;
|
|
NTSTATUS status = 0;
|
|
|
|
RtlInitUnicodeString(&name, linkname);
|
|
RtlInitUnicodeString(&target, targetname);
|
|
InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
|
|
|
status = NtCreateSymbolicLinkObject(&hLink, SYMBOLIC_LINK_ALL_ACCESS, &oa, &target);
|
|
SetLastError(RtlNtStatusToDosError(status));
|
|
if (status != 0)
|
|
{
|
|
PrintLastError(L"NtCreateSymbolicLinkObject");
|
|
return NULL;
|
|
}
|
|
|
|
return hLink;
|
|
}
|
|
|
|
BOOL TokenGetSid(HANDLE hToken, PSID* ppSid)
|
|
{
|
|
BOOL bReturnValue = TRUE;
|
|
DWORD dwSize = 0;
|
|
PTOKEN_USER pTokenUser = NULL;
|
|
|
|
if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize))
|
|
{
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
|
PrintLastError(L"GetTokenInformation");
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
pTokenUser = (PTOKEN_USER)LocalAlloc(LPTR, dwSize);
|
|
if (!pTokenUser)
|
|
goto end;
|
|
|
|
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
|
|
{
|
|
PrintLastError(L"GetTokenInformation");
|
|
goto end;
|
|
}
|
|
|
|
*ppSid = (PSID)LocalAlloc(LPTR, SECURITY_MAX_SID_SIZE);
|
|
if (!*ppSid)
|
|
goto end;
|
|
|
|
if (!CopySid(SECURITY_MAX_SID_SIZE, *ppSid, pTokenUser->User.Sid))
|
|
{
|
|
PrintLastError(L"CopySid");
|
|
LocalFree(*ppSid);
|
|
goto end;
|
|
}
|
|
|
|
bReturnValue = TRUE;
|
|
|
|
end:
|
|
if (pTokenUser)
|
|
LocalFree(pTokenUser);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL TokenGetSidAsString(HANDLE hToken, LPWSTR* ppwszStringSid)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
PSID pSid = NULL;
|
|
|
|
if (TokenGetSid(hToken, &pSid))
|
|
{
|
|
if (ConvertSidToStringSid(pSid, ppwszStringSid))
|
|
{
|
|
bReturnValue = TRUE;
|
|
}
|
|
LocalFree(pSid);
|
|
}
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL TokenCompareSids(PSID pSidA, PSID pSidB)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
LPWSTR pwszSidA = NULL;
|
|
LPWSTR pwszSidB = NULL;
|
|
|
|
if (ConvertSidToStringSid(pSidA, &pwszSidA) && ConvertSidToStringSid(pSidB, &pwszSidB))
|
|
{
|
|
bReturnValue = _wcsicmp(pwszSidA, pwszSidB) == 0;
|
|
LocalFree(pwszSidA);
|
|
LocalFree(pwszSidB);
|
|
}
|
|
else
|
|
PrintLastError(L"ConvertSidToStringSid");
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL TokenGetUsername(HANDLE hToken, LPWSTR* ppwszUsername)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
PSID pSid = NULL;
|
|
const DWORD dwMaxSize = 256;
|
|
WCHAR wszUsername[dwMaxSize] = { 0 };
|
|
WCHAR wszDomain[dwMaxSize] = { 0 };
|
|
DWORD dwMaxUsername = dwMaxSize;
|
|
DWORD dwMaxDomain = dwMaxSize;
|
|
SID_NAME_USE type;
|
|
|
|
if (!TokenGetSid(hToken, &pSid))
|
|
goto end;
|
|
|
|
if (!LookupAccountSid(NULL, pSid, wszUsername, &dwMaxUsername, wszDomain, &dwMaxDomain, &type))
|
|
{
|
|
PrintLastError(L"LookupAccountSid");
|
|
goto end;
|
|
}
|
|
|
|
*ppwszUsername = (LPWSTR)LocalAlloc(LPTR, (dwMaxSize * 2 + 1) * sizeof(WCHAR));
|
|
if (!*ppwszUsername)
|
|
goto end;
|
|
|
|
StringCchPrintf(*ppwszUsername, dwMaxSize * 2 + 1, L"%ws\\%ws", wszDomain, wszUsername);
|
|
bReturnValue = TRUE;
|
|
|
|
end:
|
|
if (pSid)
|
|
LocalFree(pSid);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL TokenCheckPrivilege(HANDLE hToken, LPCWSTR pwszPrivilege, BOOL bEnablePrivilege)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
DWORD dwTokenPrivilegesSize = 0, i = 0, dwPrivilegeNameLength = 0;
|
|
PTOKEN_PRIVILEGES pTokenPrivileges = NULL;
|
|
LUID_AND_ATTRIBUTES laa = { 0 };
|
|
TOKEN_PRIVILEGES tp = { 0 };
|
|
LPWSTR pwszPrivilegeNameTemp = NULL;
|
|
|
|
if (!GetTokenInformation(hToken, TokenPrivileges, NULL, dwTokenPrivilegesSize, &dwTokenPrivilegesSize))
|
|
{
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
PrintLastError(L"GetTokenInformation");
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
pTokenPrivileges = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, dwTokenPrivilegesSize);
|
|
if (!pTokenPrivileges)
|
|
goto end;
|
|
|
|
if (!GetTokenInformation(hToken, TokenPrivileges, pTokenPrivileges, dwTokenPrivilegesSize, &dwTokenPrivilegesSize))
|
|
{
|
|
PrintLastError(L"GetTokenInformation");
|
|
goto end;
|
|
}
|
|
|
|
for (i = 0; i < pTokenPrivileges->PrivilegeCount; i++)
|
|
{
|
|
laa = pTokenPrivileges->Privileges[i];
|
|
dwPrivilegeNameLength = 0;
|
|
|
|
if (!LookupPrivilegeName(NULL, &(laa.Luid), NULL, &dwPrivilegeNameLength))
|
|
{
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
PrintLastError(L"LookupPrivilegeName");
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
dwPrivilegeNameLength++;
|
|
|
|
if (pwszPrivilegeNameTemp = (LPWSTR)LocalAlloc(LPTR, dwPrivilegeNameLength * sizeof(WCHAR)))
|
|
{
|
|
if (LookupPrivilegeName(NULL, &(laa.Luid), pwszPrivilegeNameTemp, &dwPrivilegeNameLength))
|
|
{
|
|
if (!_wcsicmp(pwszPrivilegeNameTemp, pwszPrivilege))
|
|
{
|
|
if (bEnablePrivilege)
|
|
{
|
|
ZeroMemory(&tp, sizeof(TOKEN_PRIVILEGES));
|
|
tp.PrivilegeCount = 1;
|
|
tp.Privileges[0].Luid = laa.Luid;
|
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
|
if (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
|
|
bReturnValue = TRUE;
|
|
else
|
|
PrintLastError(L"AdjustTokenPrivileges");
|
|
}
|
|
else
|
|
{
|
|
bReturnValue = TRUE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
PrintLastError(L"LookupPrivilegeName");
|
|
|
|
LocalFree(pwszPrivilegeNameTemp);
|
|
}
|
|
}
|
|
|
|
end:
|
|
if (pTokenPrivileges)
|
|
LocalFree(pTokenPrivileges);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL TokenIsNotRestricted(HANDLE hToken, PBOOL pbIsNotRestricted)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
|
|
DWORD dwSize = 0;
|
|
PTOKEN_GROUPS pTokenGroups = NULL;
|
|
|
|
if (!GetTokenInformation(hToken, TokenRestrictedSids, NULL, dwSize, &dwSize))
|
|
{
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
PrintLastError(L"GetTokenInformation");
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
pTokenGroups = (PTOKEN_GROUPS)LocalAlloc(LPTR, dwSize);
|
|
if (!pTokenGroups)
|
|
goto end;
|
|
|
|
if (!GetTokenInformation(hToken, TokenRestrictedSids, pTokenGroups, dwSize, &dwSize))
|
|
{
|
|
PrintLastError(L"GetTokenInformation");
|
|
goto end;
|
|
}
|
|
|
|
*pbIsNotRestricted = pTokenGroups->GroupCount == 0;
|
|
|
|
bReturnValue = TRUE;
|
|
|
|
end:
|
|
if (pTokenGroups)
|
|
LocalFree(pTokenGroups);
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
BOOL MiscSystemArchIsAmd64()
|
|
{
|
|
SYSTEM_INFO sysinfo = { 0 };
|
|
GetNativeSystemInfo(&sysinfo);
|
|
return sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
|
|
}
|
|
|
|
BOOL MiscGenerateGuidString(LPWSTR* ppwszGuid)
|
|
{
|
|
BOOL bReturnValue = FALSE;
|
|
|
|
UUID uuid = { 0 };
|
|
RPC_WSTR wstrGuid = NULL;
|
|
|
|
if (UuidCreate(&uuid) != RPC_S_OK)
|
|
goto end;
|
|
|
|
if (UuidToString(&uuid, &wstrGuid) != RPC_S_OK)
|
|
goto end;
|
|
|
|
*ppwszGuid = (LPWSTR)LocalAlloc(LPTR, (wcslen((LPWSTR)wstrGuid) + 1) * sizeof(WCHAR));
|
|
if (!*ppwszGuid)
|
|
goto end;
|
|
|
|
StringCchPrintf(*ppwszGuid, wcslen((LPWSTR)wstrGuid), L"%ws", (LPWSTR)wstrGuid);
|
|
bReturnValue = TRUE;
|
|
|
|
end:
|
|
if (wstrGuid)
|
|
RpcStringFree(&wstrGuid);
|
|
|
|
return bReturnValue;
|
|
}
|