BOOL SeDebugPrivilege(HANDLE hHandle) { HANDLE hToken; DWORD dwSize; TOKEN_PRIVILEGES newPriv, oldPriv; LUID luid; if(!OpenProcessToken(hHandle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken)) { printf("[-] OpenProcessToken() error : %d", GetLastError()); return FALSE; } if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { printf("[-] LookupPrivilegeValue() error : %d", GetLastError()); return FALSE; } newPriv.PrivilegeCount = 1; newPriv.Privileges[0].Luid = luid; newPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(ERROR_NOT_ALL_ASSIGNED == AdjustTokenPrivileges(hToken, FALSE, &newPriv, sizeof(TOKEN_PRIVILEGES), &oldPriv, &dwSize)) { printf("[-] AdjustTokenPrivileges() error", GetLastError()); return FALSE; } LPSTR bName; LookupPrivilegeName(NULL, &newPriv.Privileges[0].Luid, bName, &dwSize); bName = malloc(dwSize + 1); LookupPrivilegeName(NULL, &newPriv.Privileges[0].Luid, bName, &dwSize); printf("[+] SE_PRIVILEGE_ENABLED : %s", bName); free(bName); CloseHandle(hToken); return TRUE; }
int main() { // Get the name of privilege for a LUID. LUIDs can change from a Windows version to another. LUID privilege = { 31, 0 }; wchar_t priv_name[100]; DWORD len_priv_name = sizeof(priv_name); if (LookupPrivilegeName(nullptr, &privilege, priv_name, &len_priv_name)) { std::wstring priv{ priv_name }; std::wcout << priv << std::endl; } // IID_IGlassTerminal dd 6344A5B7h; Data1 // .rdata:0000000100036320 dw 0EF1Ch; Data2 // .rdata:0000000100036320 dw 47BAh; Data3 // .rdata:0000000100036320 db 98h, 0B7h, 28h, 0C6h, 64h, 42h, 77h, 93h; Data4 IID iid_glassterminal{ 0x6344A5B7, 0x0EF1C, 0x47BA, {0x98, 0xB7, 0x28, 0xC6, 0x64, 0x42, 0x77, 0x93} }; LPOLESTR iid_string; StringFromIID(iid_glassterminal, &iid_string); std::wcout << "IID_GlassTerminal " << iid_string << std::endl; return 0; }
BOOL TokenProcess(HANDLE hToken){ DWORD dwRet = 0; TOKEN_USER *tokUser; TOKEN_GROUPS *tokGroups; TOKEN_PRIVILEGES *tokPrivs; TOKEN_OWNER *tokOwner; TOKEN_PRIMARY_GROUP *tokPrimGroup; TOKEN_DEFAULT_DACL *tokDACL; TOKEN_SOURCE tokSource; TOKEN_TYPE tokType; SECURITY_IMPERSONATION_LEVEL *tokImpersonationLvl; TOKEN_STATISTICS *tokStats; DWORD tokSessionID; TOKEN_GROUPS_AND_PRIVILEGES *tokGrpPrivs; DWORD dwSandboxInert; TOKEN_ORIGIN *tokOrigin; TOKEN_ELEVATION_TYPE tokElevType; TOKEN_LINKED_TOKEN *tokLinkedToken; TOKEN_ELEVATION tokElev; DWORD tokHasRestrictions; TOKEN_ACCESS_INFORMATION *tokAccessInformation; DWORD tokVirtAllowed; DWORD tokVirtEnabled; TOKEN_MANDATORY_LABEL *tokIntegrityLevel; DWORD tokUIAccess; TOKEN_MANDATORY_POLICY *tokMandaPolicy; TOKEN_GROUPS *tokLogonSid; DWORD tokAppContainer; TOKEN_GROUPS *tokCapabilities; //TOKEN_APPCONTAINER_INFORMATION tokAppContainerNfo; DWORD tokContainerNumber; //CLAIM_SECURITY_ATTRIBUTES_INFORMATION tokClaimAttributes; GetTokenInformation(hToken,TokenSource,&tokSource,sizeof(tokSource),&dwRet); GetTokenInformation(hToken,TokenType,&tokType,sizeof(tokType),&dwRet); GetTokenInformation(hToken,TokenElevationType,&tokElevType,sizeof(tokElevType),&dwRet); GetTokenInformation(hToken,TokenElevation,&tokElev,sizeof(tokElev),&dwRet); char strType[200]; if(tokType == TokenPrimary) strcpy_s(strType,"Primary"); else strcpy_s(strType,"Impersonation"); char strElevated[200]; if(tokElevType == TokenElevationTypeDefault) strcpy_s(strElevated,"No linked token"); else if(tokElevType == TokenElevationTypeFull) strcpy_s(strElevated,"Elevated token"); else if(tokElevType == TokenElevationTypeLimited) strcpy_s(strElevated,"Limited token"); fprintf(stdout,"[i] +-+-> Token [%08x] - Token source: %s - Token type %s - %s - %s\n",hToken,tokSource.SourceName,strType,strElevated, tokElev.TokenIsElevated ? "Elevated privs" : "Normal privs" ); // User GetTokenInformation(hToken,TokenOwner,NULL,0,&dwRet); tokOwner = (TOKEN_OWNER*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenOwner,tokOwner,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokOwner->Owner, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Owner: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> Owner: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokOwner); // User GetTokenInformation(hToken,TokenUser,NULL,0,&dwRet); tokUser = (TOKEN_USER*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenUser,tokUser,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokUser->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> User: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> User: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokUser); // Groups GetTokenInformation(hToken,TokenGroups,NULL,0,&dwRet); tokGroups = (TOKEN_GROUPS*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenGroups,tokGroups,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; for(DWORD dwCount=0;dwCount<tokGroups->GroupCount;dwCount++){ dwSize=2048; if( LookupAccountSidA( NULL, tokGroups->Groups[dwCount].Sid, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Group: %s\\%s\n",lpDomain,lpName); } else { if(GetLastError() == ERROR_NONE_MAPPED ){ fprintf(stdout,"[i] +-+-> Group: None Mapped\n"); } else { fprintf(stdout,"[i] +-+-> Group: %s (%d)\n",sidToTextTok(tokGroups->Groups[dwCount].Sid),GetLastError()); } } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_ENABLED) { fprintf(stdout,"[i] +-> Enabled\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_ENABLED_BY_DEFAULT) { fprintf(stdout,"[i] +-> Enabled by default\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_INTEGRITY) { fprintf(stdout,"[i] +-> Integrity SID\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_INTEGRITY_ENABLED) { fprintf(stdout,"[i] +-> Integrity enabled\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_LOGON_ID) { fprintf(stdout,"[i] +-> Logon SID\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_MANDATORY) { fprintf(stdout,"[i] +-> Mandatory\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_OWNER) { fprintf(stdout,"[i] +-> Owner\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_RESOURCE) { fprintf(stdout,"[i] +-> Domain-local group\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_OWNER) { fprintf(stdout,"[i] +-> Owner\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_USE_FOR_DENY_ONLY) { fprintf(stdout,"[i] +-> Deny only SID\n"); } } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokGroups); // Privs GetTokenInformation(hToken,TokenPrivileges,NULL,0,&dwRet); tokPrivs = (TOKEN_PRIVILEGES*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenPrivileges,tokPrivs,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Privileges - %d\n",tokPrivs->PrivilegeCount); for(DWORD dwCount=0;dwCount<tokPrivs->PrivilegeCount;dwCount++){ DWORD dwSize = 2048; char lpName[2048]; LUID lFoo = tokPrivs->Privileges[dwCount].Luid; if(LookupPrivilegeName(NULL,&lFoo,lpName,&dwSize)){ fprintf(stdout,"[i] +-> Name: %s\n",lpName); } else { fprintf(stdout,"[i] +-> Name: Unknown (%d)\n",GetLastError()); } } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokPrivs); // Token owner GetTokenInformation(hToken,TokenOwner,NULL,0,&dwRet); tokOwner = (TOKEN_OWNER*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenOwner,tokOwner,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokOwner->Owner, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Owner: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> Owner: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokOwner); // Primary group GetTokenInformation(hToken,TokenPrimaryGroup,NULL,0,&dwRet); tokPrimGroup = (TOKEN_PRIMARY_GROUP *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenPrimaryGroup,tokPrimGroup,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokPrimGroup->PrimaryGroup, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Primary group: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> Primary group: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokPrimGroup); // Sandbox inert if(GetTokenInformation(hToken,TokenSandBoxInert,&dwSandboxInert,sizeof(dwSandboxInert),&dwRet)){ if(dwSandboxInert > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - Sandbox inert\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // UI Access if(GetTokenInformation(hToken,TokenUIAccess,&tokUIAccess,sizeof(tokUIAccess),&dwRet)){ if(tokUIAccess > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - UI Access\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // Integirty level bool bLow = false; bool bUntrusted = false; GetTokenInformation(hToken,TokenIntegrityLevel,NULL,0,&dwRet); tokIntegrityLevel = (TOKEN_MANDATORY_LABEL *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenIntegrityLevel,tokIntegrityLevel ,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokIntegrityLevel->Label.Sid, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Integrity level: %s\\%s\n",lpDomain,lpName); if(strcmp(lpName,"Low Mandatory Level") ==0) { bLow = true; } else if (strcmp(lpName,"Untrusted Mandatory Level") == 0){ bUntrusted = true; } } else { fprintf(stdout,"[i] +-+-> Integrity level: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokIntegrityLevel); // Virtualisation allowed if(GetTokenInformation(hToken,TokenVirtualizationAllowed,&tokVirtAllowed,sizeof(tokVirtAllowed),&dwRet)){ if(tokVirtAllowed > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> UAC virtualisation allowed\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // Virtualisation enabled if(GetTokenInformation(hToken,TokenVirtualizationEnabled,&tokVirtEnabled,sizeof(tokVirtEnabled),&dwRet)){ if(tokVirtEnabled > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> UAC virtualisation enabled\n"); } else { if(bLow){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - UAC virtualisation disabled for low LI process\n"); } else if(bUntrusted){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - UAC virtualisation disabled for untrusted LI process\n"); } else { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> UAC virtualisation disabled but of no great concern\n"); } } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // Default DACL GetTokenInformation(hToken,TokenDefaultDacl,NULL,0,&dwRet); tokDACL = (TOKEN_DEFAULT_DACL*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenDefaultDacl,tokDACL,dwRet,&dwRet) == true){ PrintPermissionsTok(tokDACL->DefaultDacl); } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokDACL); return true; }
/* * http://www.ddj.com/windows/184405986 * * There's a way to determine whether we're running under the Local System * account. However (you guessed it), we have to call more Win32 functions to * determine this. Backing up through the code listing, we need to make another * call to GetTokenInformation, but instead of passing through the TOKEN_USER * constant, we pass through the TOKEN_PRIVILEGES constant. This value returns * an array of privileges that the account has in the environment. Iterating * through the array, we call the function LookupPrivilegeName looking for the * string “SeTcbPrivilege. If the function returns this string, then this * account has Local System privileges */ int HasSystemPrivilege(HANDLE hProcess) { DWORD i; DWORD dwSize = 0; DWORD dwRetval = 0; TCHAR privName[256]; DWORD dwNameSize = 256; //PTOKEN_PRIVILEGES tp = NULL; BYTE *pBuffer = NULL; TOKEN_PRIVILEGES* tp = NULL; HANDLE hToken = token_from_handle(hProcess); if (NULL == hToken) { return -1; } // call GetTokenInformation first to get the buffer size if (! GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) { dwRetval = GetLastError(); // if it failed for a reason other than the buffer, bail out if (dwRetval != ERROR_INSUFFICIENT_BUFFER ) { PyErr_SetFromWindowsErr(dwRetval); return 0; } } // allocate buffer and call GetTokenInformation again //tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize); pBuffer = (BYTE *) malloc(dwSize); if (pBuffer == NULL) { PyErr_SetFromWindowsErr(0); LocalFree(pBuffer); return -1; } if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer, dwSize, &dwSize) ) { PyErr_SetFromWindowsErr(0); LocalFree(pBuffer); return -1; } // convert the BYTE buffer to a TOKEN_PRIVILEGES struct pointer tp = (TOKEN_PRIVILEGES*)pBuffer; // check all the privileges looking for SeTcbPrivilege for(i=0; i < tp->PrivilegeCount; i++) { // reset the buffer contents and the buffer size strcpy(privName, ""); dwNameSize = sizeof(privName) / sizeof(TCHAR); if (! LookupPrivilegeName(NULL, &tp->Privileges[i].Luid, (LPTSTR)privName, &dwNameSize)) { PyErr_SetFromWindowsErr(0); free(pBuffer); return -1; } // if we find the SeTcbPrivilege then it's a LocalSystem process if (! lstrcmpi(privName, TEXT("SeTcbPrivilege"))) { free(pBuffer); return 1; } } //for free(pBuffer); return 0; }
VOID HsQueryProcessPrivilege(CMyList *m_ListCtrl) { ULONG_PTR ProcessID = g_ulProcessId; ULONG dwReturnSize = 0; ULONG dwRet = 0; PVOID Temp = NULL; ULONG nSize = 1000; if (ProcessID == 0) { return; } m_ListCtrl->DeleteAllItems(); Temp = (PTOKEN_PRIVILEGES)malloc(sizeof(char)*nSize); if (!Temp) { return; } dwRet = DeviceIoControl(g_hDevice,HS_IOCTL(HS_IOCTL_PROC_PROCESSPRIVILEGE), &ProcessID, sizeof(ULONG_PTR), Temp, nSize, &dwReturnSize, NULL); if (dwRet && ((PTOKEN_PRIVILEGES)Temp)->PrivilegeCount > 0) { for (ULONG i = 0; i <((PTOKEN_PRIVILEGES)Temp)->PrivilegeCount;i++) { WCHAR PrivilegeName[MAX_PATH] = {0}; WCHAR DisplayName[MAX_PATH] = {0}; DWORD LanguageId = 0; DWORD dwRet1 = MAX_PATH; DWORD dwRet2 = MAX_PATH; LookupPrivilegeName(NULL, &((PTOKEN_PRIVILEGES)Temp)->Privileges[i].Luid, PrivilegeName, &dwRet1); LookupPrivilegeDisplayName(NULL,PrivilegeName,DisplayName,&dwRet2,&LanguageId); printf("%S\r\n",PrivilegeName); wprintf(L"%s",DisplayName); if (wcslen(PrivilegeName) == 0) { break; } m_ListCtrl->InsertItem(i, PrivilegeName); m_ListCtrl->SetItemText(i,1,DisplayName); if (((PTOKEN_PRIVILEGES)Temp)->Privileges[i].Attributes & 1) { //printf("\t\tDefault Enabled"); m_ListCtrl->SetItemText(i,2,L"Default Enabled"); } else if ( ((PTOKEN_PRIVILEGES)Temp)->Privileges[i].Attributes & 2 ) { //printf("\t\tEnabled"); m_ListCtrl->SetItemText(i,2,L"Enabled"); } else { //printf("\t\tDisabled"); m_ListCtrl->SetItemText(i,2,L"Disabled"); } } } //发送IO 控制码 if (dwRet==0) { //cout<<"Send IoCode Error"<<endl; } if (Temp!=NULL) { free(Temp); } return; }
int main(void) { int i; char user_name[250]; DWORD user_num = 250; char computer_name[250]; DWORD computer_num = 250; if (!GetComputerName( computer_name, &computer_num)) printf("%08x\n", GetLastError()); else printf("Computer: %s\n", computer_name); if (!GetUserName( user_name, &user_num)) printf("%08x\n", GetLastError()); else printf("User: %s\n", user_name); HANDLE h_me = GetCurrentProcess(); HANDLE h_token; /* Use GetKernelObjectSecurity ?*/ OpenProcessToken( h_me, TOKEN_READ, &h_token); TOKEN_USER * ptok_usr = (TOKEN_USER *) malloc( MAXSIZE ); DWORD ret; if (!GetTokenInformation (h_token, TokenUser, ptok_usr, MAXSIZE, &ret)) { print_error(); return; } char * stringsid; if (!ConvertSidToStringSidA( ptok_usr->User.Sid, &stringsid)) { print_error(); return; } printf("Sid: %s\n",stringsid); LocalFree(stringsid); fflush(stdout); getchar(); TOKEN_GROUPS *ptg; // token groups ptg = (TOKEN_GROUPS *) malloc( MAXSIZE ); if ( ! GetTokenInformation( h_token, TokenGroups, ptg, MAXSIZE, &ret ) ) { print_error(); return; } else { if ( ptg->GroupCount == 0 ) printf( "Token groups: (none)\n" ); else { printf( "Token groups:\n" ); for ( i = 0; i < ptg->GroupCount; ++ i ) { char * strsid; if (!ConvertSidToStringSidA( ptg->Groups[i].Sid, &strsid)) { print_error(); return; } printf("Group Sid: %40s",strsid); LocalFree(stringsid); char name[MAXSIZE]; char domain[MAXSIZE]; DWORD i_name=MAXSIZE, i_domain=MAXSIZE; SID_NAME_USE snu; if(!LookupAccountSidA(NULL, ptg->Groups[i].Sid, name, &i_name, domain, &i_domain, &snu)) { print_error(); } else { printf("\t %s\\%s\n", domain, name); } } } } fflush(stdout); getchar(); UCHAR privbuf[1000]; PTOKEN_PRIVILEGES ptgPrivileges = (PTOKEN_PRIVILEGES) privbuf; DWORD privilegeNameSize; DWORD displayNameSize; char privilegeName[500]; char displayName[500]; DWORD langId; if (!GetTokenInformation (h_token, TokenPrivileges, privbuf, sizeof(privbuf), &ret)) { print_error(); return; } printf( "Account privileges: \n\n" ); for( i = 0; i < ptgPrivileges->PrivilegeCount; i ++ ) { privilegeNameSize = sizeof privilegeName; displayNameSize = sizeof displayName; LookupPrivilegeName( NULL, &ptgPrivileges->Privileges[i].Luid, privilegeName, &privilegeNameSize ); LookupPrivilegeDisplayName( NULL, privilegeName, displayName, &displayNameSize, &langId ); printf( "%40s (%s)\n", displayName, privilegeName ); } fflush(stdout); getchar(); return 0; }
// Attempts to enable the SE_DEBUG_NAME privilege. If the privilege is unavailable, // this intentionally returns S_OK, as same-user attach is still supported without need // for the SE_DEBUG_NAME privilege HRESULT EnableDebugPrivilege() { HRESULT hr; HANDLE hProcessToken = NULL; LPBYTE pbTokenInformation = NULL; if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hProcessToken)) { hr = HRESULT_FROM_WIN32(GetLastError()); Log(L"Error returned from OpenProcessToken. hr = 0x%x.\n", hr); goto Cleanup; } DWORD cbTokenInformationOut; if (!GetTokenInformation( hProcessToken, TokenPrivileges, NULL, // TokenInformation 0, // TokenInformationLength, &cbTokenInformationOut)) { DWORD dwLastError = GetLastError(); if (dwLastError != ERROR_INSUFFICIENT_BUFFER) { hr = HRESULT_FROM_WIN32(dwLastError); Log(L"Error returned from GetTokenInformation. hr = 0x%x.\n", hr); goto Cleanup; } } DWORD cbTokenInformation = cbTokenInformationOut; pbTokenInformation = new BYTE[cbTokenInformation]; if (pbTokenInformation == NULL) { hr = E_OUTOFMEMORY; Log(L"Unable to allocate %d bytes for token information.\n", cbTokenInformation); goto Cleanup; } if (!GetTokenInformation( hProcessToken, TokenPrivileges, pbTokenInformation, cbTokenInformation, &cbTokenInformationOut)) { hr = HRESULT_FROM_WIN32(GetLastError()); Log(L"Error returned from GetTokenInformation. hr = 0x%x.\n", hr); goto Cleanup; } TOKEN_PRIVILEGES * pPrivileges = (TOKEN_PRIVILEGES *) pbTokenInformation; BOOL fFoundDebugPrivilege = FALSE; LUID_AND_ATTRIBUTES * pLuidAndAttrs = NULL; for (DWORD i=0; i < pPrivileges->PrivilegeCount; i++) { pLuidAndAttrs = &(pPrivileges->Privileges[i]); WCHAR wszPrivilegeName[100]; DWORD cchPrivilegeName = ARRAY_LEN(wszPrivilegeName); if (!LookupPrivilegeName( NULL, // lpSystemName &(pLuidAndAttrs->Luid), &(wszPrivilegeName[0]), &cchPrivilegeName)) { hr = HRESULT_FROM_WIN32(GetLastError()); Log(L"Error returned from LookupPrivilegeName. hr = 0x%x.\n", hr); goto Cleanup; } if (wcscmp(wszPrivilegeName, SE_DEBUG_NAME) == 0) { fFoundDebugPrivilege = TRUE; break; } } if (!fFoundDebugPrivilege) { //Unable to find SeDebugPrivilege; user may not be able to profile higher integrity proceses. //return silently and give it a try. //if the attach failed, let the customer know they can run CLRProfiler as administrator and try again. hr = E_FAIL; goto Cleanup; } if ((pLuidAndAttrs->Attributes & SE_PRIVILEGE_ENABLED) != 0) { // Privilege already enabled. Nothing to do. hr = S_OK; // Log(L"SeDebugPrivilege is already enabled.\n"); goto Cleanup; } // Log(L"SeDebugPrivilege available but disabled. Attempting to enable it...\n"); pLuidAndAttrs->Attributes |= SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges( hProcessToken, FALSE, // DisableAllPrivileges, pPrivileges, cbTokenInformationOut, NULL, // PreviousState, NULL // ReturnLength )) { hr = HRESULT_FROM_WIN32(GetLastError()); Log(L"Error returned from AdjustTokenPrivileges. hr = 0x%x.\n", hr); goto Cleanup; } hr = S_OK; Cleanup: if (hProcessToken != NULL) { CloseHandle(hProcessToken); hProcessToken = NULL; } if (pbTokenInformation != NULL) { delete [] pbTokenInformation; pbTokenInformation = NULL; } return hr; }