static HANDLE s_GetThreadToken(DWORD access) { HANDLE token; if ( !OpenThreadToken(GetCurrentThread(), access, FALSE, &token) ) { DWORD res = GetLastError(); if ( res == ERROR_NO_TOKEN ) { if ( !ImpersonateSelf(SecurityImpersonation) ) { // Failed to obtain a token for the current thread and user CNcbiError::SetFromWindowsError(); return INVALID_HANDLE_VALUE; } if ( !OpenThreadToken(GetCurrentThread(), access, FALSE, &token) ) { // Failed to open the current threads token with the required access rights CNcbiError::SetFromWindowsError(); token = INVALID_HANDLE_VALUE; } RevertToSelf(); } else { // Failed to open the current threads token with the required access rights CNcbiError::SetWindowsError(res); return NULL; } } return token; }
int UnsetSeDebug() { HANDLE hToken; if(! OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken) ){ if(GetLastError() == ERROR_NO_TOKEN){ if(! ImpersonateSelf(SecurityImpersonation)){ //Log2File("Error setting impersonation! [UnsetSeDebug()]", L_DEBUG); return 0; } if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken) ){ //Log2File("Error Opening Thread Token! [UnsetSeDebug()]", L_DEBUG); return 0; } } } //now disable SeDebug if(!SetPrivilege(hToken, SE_DEBUG_NAME, FALSE)){ //Log2File("Error unsetting SeDebug Privilege [SetPrivilege()]", L_WARN); return 0; } CloseHandle(hToken); return 1; }
void CWE252_Unchecked_Return_Value__w32ImpersonateSelf_05_bad() { if(staticTrue) { /* FLAW: Do not check if ImpersonateSelf() fails */ ImpersonateSelf(SecurityImpersonation); } }
/* good1() reverses the blocks on the goto statement */ static void good1() { goto sink; sink: /* FIX: check for the correct return value */ if (!ImpersonateSelf(SecurityImpersonation)) { exit(1); } }
void CWE253_Incorrect_Check_of_Function_Return_Value__w32_ImpersonateSelf_18_bad() { goto sink; sink: /* FLAW: ImpersonateSelf() could fail and would return 0 (false), but we are checking to see * if the return value is greater than zero (true) */ if (ImpersonateSelf(SecurityImpersonation) > 0) { exit(1); } }
/* good2() reverses the bodies in the if statement */ static void good2() { if(staticTrue) { /* FIX: Check to see if ImpersonateSelf() fails */ if (!ImpersonateSelf(SecurityImpersonation)) { exit(1); } } }
/* good2() reverses the bodies in the if statement */ static void good2() { if(globalFive==5) { /* FIX: check for the correct return value */ if (!ImpersonateSelf(SecurityImpersonation)) { exit(1); } } }
/* good2() reverses the bodies in the if statement */ static void good2() { if(STATIC_CONST_FIVE==5) { /* FIX: check for the correct return value */ if (!ImpersonateSelf(SecurityImpersonation)) { exit(1); } } }
/** * @brief adjust privilege * @param * @see * @remarks http://support.microsoft.com/kb/131065/EN-US/ * @code * @endcode * @return */ bool set_privilege(_In_z_ const wchar_t* privilege, _In_ bool enable) { HANDLE token = INVALID_HANDLE_VALUE; if (TRUE != OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &token) ) { if (ERROR_NO_TOKEN == GetLastError() ) { if ( ImpersonateSelf(SecurityImpersonation) != TRUE ) { return FALSE; } if (TRUE != OpenThreadToken(GetCurrentThread(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,FALSE,&token) ) { return FALSE; } } else { return FALSE; } } TOKEN_PRIVILEGES tp = { 0 }; LUID luid = {0}; DWORD cb = sizeof(TOKEN_PRIVILEGES); bool ret = false; do { if(!LookupPrivilegeValueW( NULL, privilege, &luid )) { break; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if(enable) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { tp.Privileges[0].Attributes = 0; } AdjustTokenPrivileges( token, FALSE, &tp, cb, NULL, NULL ); if (GetLastError() != ERROR_SUCCESS) { break; } ret = true; } while (false); CloseHandle(token); return ret; }
/* This function is still a proof of concept, it's probably rife with bugs, below is a short (and incomplete) todo * "Basic" checks (Read/Write/File/Dir) checks for FAT32 filesystems which requires detecting the filesystem being used. */ void Check(fs::path const& file, acs::Type type) { DWORD file_attr = GetFileAttributes(file.c_str()); if ((file_attr & INVALID_FILE_ATTRIBUTES) == INVALID_FILE_ATTRIBUTES) { switch (GetLastError()) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: throw fs::FileNotFound(file); case ERROR_ACCESS_DENIED: throw fs::ReadDenied(file); default: throw fs::FileSystemUnknownError(str(boost::format("Unexpected error when getting attributes for \"%s\": %s") % file % util::ErrorString(GetLastError()))); } } switch (type) { case FileRead: case FileWrite: if ((file_attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) throw fs::NotAFile(file); break; case DirRead: case DirWrite: if ((file_attr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) throw fs::NotADirectory(file); break; } SECURITY_INFORMATION info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; DWORD len = 0; GetFileSecurity(file.c_str(), info, nullptr, 0, &len); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) LOG_W("acs/check") << "GetFileSecurity: fatal: " << util::ErrorString(GetLastError()); std::vector<uint8_t> sd_buff(len); SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&sd_buff[0]; if (!GetFileSecurity(file.c_str(), info, sd, len, &len)) LOG_W("acs/check") << "GetFileSecurity failed: " << util::ErrorString(GetLastError()); ImpersonateSelf(SecurityImpersonation); HANDLE client_token; if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &client_token)) LOG_W("acs/check") << "OpenThreadToken failed: " << util::ErrorString(GetLastError()); if (!check_permission(true, sd, client_token)) throw fs::ReadDenied(file); if ((type == DirWrite || type == FileWrite) && !check_permission(false, sd, client_token)) throw fs::WriteDenied(file); }
/* good1() uses if(staticFalse) instead of if(staticTrue) */ static void good1() { if(staticFalse) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { /* FIX: Check to see if ImpersonateSelf() fails */ if (!ImpersonateSelf(SecurityImpersonation)) { exit(1); } } }
/* good1() uses if(STATIC_CONST_FIVE!=5) instead of if(STATIC_CONST_FIVE==5) */ static void good1() { if(STATIC_CONST_FIVE!=5) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { /* FIX: check for the correct return value */ if (!ImpersonateSelf(SecurityImpersonation)) { exit(1); } } }
// If the process is owned by another user, request SeDebugPrivilege to open it. // Debug privileges are typically granted to Administrators. static int enable_debug_privileges() { HANDLE hToken; if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &hToken)) { if (!ImpersonateSelf(SecurityImpersonation) || !OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &hToken)) { return 0; } } LUID luid; if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { return 0; } TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; BOOL success = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); CloseHandle(hToken); return success ? 1 : 0; }
int SetSeDebug() { HANDLE hToken; if(! OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken) ){ if (GetLastError() == ERROR_NO_TOKEN){ if (!ImpersonateSelf(SecurityImpersonation)){ CloseHandle(hToken); return 0; } if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken) ){ RevertToSelf(); CloseHandle(hToken); return 0; } } } // enable SeDebugPrivilege (open any process) if (! SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)){ RevertToSelf(); CloseHandle(hToken); return 0; } RevertToSelf(); CloseHandle(hToken); return 1; }
bool set_privilege(_In_z_ const wchar_t* privilege, _In_ bool enable) { if (IsWindowsXPOrGreater()) { HANDLE hToken; if (TRUE != OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)) { if (GetLastError() == ERROR_NO_TOKEN) { if (ImpersonateSelf(SecurityImpersonation) != TRUE) { printf("ImpersonateSelf( ) failed. gle=0x%08x", GetLastError()); return false; } if (TRUE != OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)) { printf("OpenThreadToken() failed. gle=0x%08x", GetLastError()); return false; } } else { printf("OpenThread() failed. gle=0x%08x", GetLastError()); return false; } } TOKEN_PRIVILEGES tp = { 0 }; LUID luid = { 0 }; DWORD cb = sizeof(TOKEN_PRIVILEGES); if (!LookupPrivilegeValue(NULL, privilege, &luid)) { printf("LookupPrivilegeValue() failed. gle=0x%08x", GetLastError()); CloseHandle(hToken); return false; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (enable) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { tp.Privileges[0].Attributes = 0; } if (FALSE == AdjustTokenPrivileges(hToken, FALSE, &tp, cb, NULL, NULL)) { DWORD gle = GetLastError(); if (gle != ERROR_SUCCESS) { printf("AdjustTokenPrivileges() failed. gle=0x%08x", GetLastError()); CloseHandle(hToken); return false; } } CloseHandle(hToken); } return true; }
/* ** Wrapper around the access() system call. This code was copied from Tcl ** 8.6 and then modified. */ int win32_access(const char *zFilename, int flags){ int rc = 0; PSECURITY_DESCRIPTOR pSd = NULL; unsigned long size; PSID pSid = NULL; BOOL sidDefaulted; BOOL impersonated = FALSE; SID_IDENTIFIER_AUTHORITY unmapped = {{0, 0, 0, 0, 0, 22}}; GENERIC_MAPPING genMap; HANDLE hToken = NULL; DWORD desiredAccess = 0, grantedAccess = 0; BOOL accessYesNo = FALSE; PRIVILEGE_SET privSet; DWORD privSetSize = sizeof(PRIVILEGE_SET); wchar_t *zMbcs = fossil_utf8_to_filename(zFilename); DWORD attr = GetFileAttributesW(zMbcs); if( attr==INVALID_FILE_ATTRIBUTES ){ /* * File might not exist. */ if( GetLastError()!=ERROR_SHARING_VIOLATION ){ rc = -1; goto done; } } if( flags==F_OK ){ /* * File exists, nothing else to check. */ goto done; } if( (flags & W_OK) && (attr & FILE_ATTRIBUTE_READONLY) && !(attr & FILE_ATTRIBUTE_DIRECTORY) ){ /* * The attributes say the file is not writable. If the file is a * regular file (i.e., not a directory), then the file is not * writable, full stop. For directories, the read-only bit is * (mostly) ignored by Windows, so we can't ascertain anything about * directory access from the attrib data. */ rc = -1; goto done; } /* * It looks as if the permissions are ok, but if we are on NT, 2000 or XP, * we have a more complex permissions structure so we try to check that. * The code below is remarkably complex for such a simple thing as finding * what permissions the OS has set for a file. */ /* * First find out how big the buffer needs to be. */ size = 0; GetFileSecurityW(zMbcs, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, 0, 0, &size); /* * Should have failed with ERROR_INSUFFICIENT_BUFFER */ if( GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){ /* * Most likely case is ERROR_ACCESS_DENIED, which we will convert to * EACCES - just what we want! */ rc = -1; goto done; } /* * Now size contains the size of buffer needed. */ pSd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), 0, size); if( pSd==NULL ){ rc = -1; goto done; } /* * Call GetFileSecurity() for real. */ if( !GetFileSecurityW(zMbcs, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, pSd, size, &size) ){ /* * Error getting owner SD */ rc = -1; goto done; } /* * As of Samba 3.0.23 (10-Jul-2006), unmapped users and groups are * assigned to SID domains S-1-22-1 and S-1-22-2, where "22" is the * top-level authority. If the file owner and group is unmapped then * the ACL access check below will only test against world access, * which is likely to be more restrictive than the actual access * restrictions. Since the ACL tests are more likely wrong than * right, skip them. Moreover, the unix owner access permissions are * usually mapped to the Windows attributes, so if the user is the * file owner then the attrib checks above are correct (as far as they * go). */ if( !GetSecurityDescriptorOwner(pSd, &pSid, &sidDefaulted) || memcmp(GetSidIdentifierAuthority(pSid), &unmapped, sizeof(SID_IDENTIFIER_AUTHORITY))==0 ){ goto done; /* Attrib tests say access allowed. */ } /* * Perform security impersonation of the user and open the resulting * thread token. */ if( !ImpersonateSelf(SecurityImpersonation) ){ /* * Unable to perform security impersonation. */ rc = -1; goto done; } impersonated = TRUE; if( !OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, FALSE, &hToken) ){ /* * Unable to get current thread's token. */ rc = -1; goto done; } /* * Setup desiredAccess according to the access priveleges we are * checking. */ if( flags & R_OK ){ desiredAccess |= FILE_GENERIC_READ; } if( flags & W_OK){ desiredAccess |= FILE_GENERIC_WRITE; } memset(&genMap, 0, sizeof(GENERIC_MAPPING)); genMap.GenericRead = FILE_GENERIC_READ; genMap.GenericWrite = FILE_GENERIC_WRITE; genMap.GenericExecute = FILE_GENERIC_EXECUTE; genMap.GenericAll = FILE_ALL_ACCESS; /* * Perform access check using the token. */ if( !AccessCheck(pSd, hToken, desiredAccess, &genMap, &privSet, &privSetSize, &grantedAccess, &accessYesNo) ){ /* * Unable to perform access check. */ rc = -1; goto done; } if( !accessYesNo ) rc = -1; done: if( hToken != NULL ){ CloseHandle(hToken); } if( impersonated ){ RevertToSelf(); impersonated = FALSE; } if( pSd!=NULL ){ HeapFree(GetProcessHeap(), 0, pSd); } fossil_filename_free(zMbcs); return rc; }
/* * Attempts to enable the SE_DEBUG_NAME privilege and open the given process. */ static HANDLE doPrivilegedOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId) { HANDLE hToken; HANDLE hProcess = NULL; LUID luid; TOKEN_PRIVILEGES tp, tpPrevious; DWORD retLength, error; /* * Get the access token */ if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, FALSE, &hToken)) { if (GetLastError() != ERROR_NO_TOKEN) { return (HANDLE)NULL; } /* * No access token for the thread so impersonate the security context * of the process. */ if (!ImpersonateSelf(SecurityImpersonation)) { return (HANDLE)NULL; } if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, FALSE, &hToken)) { return (HANDLE)NULL; } } /* * Get LUID for the privilege */ if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { error = GetLastError(); CloseHandle(hToken); SetLastError(error); return (HANDLE)NULL; } /* * Enable the privilege */ ZeroMemory(&tp, sizeof(tp)); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tp.Privileges[0].Luid = luid; error = 0; if (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &tpPrevious, &retLength)) { /* * If we enabled the privilege then attempt to open the * process. */ if (GetLastError() == ERROR_SUCCESS) { hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); if (hProcess == NULL) { error = GetLastError(); } } else { error = ERROR_ACCESS_DENIED; } /* * Revert to the previous privileges */ AdjustTokenPrivileges(hToken, FALSE, &tpPrevious, retLength, NULL, NULL); } else { error = GetLastError(); } /* * Close token and restore error */ CloseHandle(hToken); SetLastError(error); return hProcess; }
bool bearlib::terminateProcess(unsigned int PID) { //取得除錯權限 HANDLE hProcess; HANDLE hToken; if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)) { if (GetLastError() == ERROR_NO_TOKEN) { if (!ImpersonateSelf(SecurityImpersonation)) { return false; } if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)) { return false; } } else { return false; } } //開啟SeDebugPrivilege TOKEN_PRIVILEGES tp = { 0 }; LUID luid; DWORD cb = sizeof(TOKEN_PRIVILEGES); if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { CloseHandle(hToken); return false; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tp, cb, NULL, NULL); if (GetLastError() != ERROR_SUCCESS) { //無法取得SeDebugPrivilege CloseHandle(hToken); return false; } //開啟程序 if((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID)) == NULL) { //無法開啟程序 ... 程序不存在?! CloseHandle(hToken); return false; } if(!TerminateProcess(hProcess, 0xffffffff)) { //無法關閉程序?!(遇到那1%了) CloseHandle(hToken); CloseHandle(hProcess); return false; } CloseHandle(hToken); CloseHandle(hProcess); //成功 return true; }
MI_Result ScheduleRestart( _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Uint32 dwError = ERROR_SUCCESS; HANDLE hToken; MI_Boolean bRevertToSelf = MI_FALSE; Intlstr intlstr = Intlstr_Null; MI_Result result = MI_RESULT_OK; if (cimErrorDetails == NULL) { return MI_RESULT_INVALID_PARAMETER; } *cimErrorDetails = NULL; // Explicitly set *cimErrorDetails to NULL as _Outptr_ requires setting this at least once. DSC_EventWriteMessageScheduleReboot(); GetResourceString(ID_LCMHELPER_SHUTDOWN_MESSAGE, &intlstr); if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &hToken)) { if (GetLastError() == ERROR_NO_TOKEN) { SetLastError(ERROR_SUCCESS); if (!ImpersonateSelf(SecurityImpersonation)) { return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); } if (!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &hToken)) { RevertToSelf(); return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); } bRevertToSelf = MI_TRUE; } else { return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); } } result = EnableShutdownPrivilege(hToken, cimErrorDetails); if (result != MI_RESULT_OK) { if (bRevertToSelf) { RevertToSelf(); } return result; } #ifdef _PREFAST_ #pragma prefast (push) #pragma prefast (disable: 28159) //This is needed to reconfigure windows server to finish configuring the system by DSC. #endif /* _PREFAST_ */ dwError = InitiateSystemShutdownEx(NULL, (MI_Char*)intlstr.str, DSC_REBOOT_GRACEPERIOD, TRUE, TRUE, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED); #ifdef _PREFAST_ #pragma prefast (pop) #endif /* _PREFAST_ */ if (bRevertToSelf) { RevertToSelf(); } if (intlstr.str ) { Intlstr_Free(intlstr); } if (!dwError) { return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_SHUTDOWN_FAILED); } return MI_RESULT_OK; }
BOOL IsUserAdmin( VOID ) /*++ Routine Description: This routine returns TRUE if the caller's process is a member of the Administrators local group. Caller is NOT expected to be impersonating anyone and IS expected to be able to open their own process and process token. Arguments: None. Return Value: TRUE - Caller has Administrators local group. FALSE - Caller does not have Administrators local group. --*/ { HANDLE Token; BOOL b = FALSE; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PSID AdministratorsGroup = NULL; ImpersonateSelf( SecurityImpersonation ); // // Open the process token. // if (OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, FALSE, &Token)) { try { // // Get SID for Administrators group // b = AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup ); if (!b) { leave; } // // Check to see if that group is currently enabled. Failure // means that we aren't administrator // if (!CheckTokenMembership( Token, AdministratorsGroup, &b )) { printf("Failure - %d\n", GetLastError( )); b = FALSE; } } finally { CloseHandle(Token); } } RevertToSelf( ); return(b); }
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); //UNREFERENCED_PARAMETER(lpCmdLine); char ** Command = 0; CommandLineToArg(GetCommandLine(), &Command); if( strcmp("Updater", Command[1]) ) { MessageBox(0, "Please start game from Launcher", "Start Error", ERROR); ExitProcess(0); } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); HANDLE hToken; VMBEGIN if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)) { if (GetLastError() == ERROR_NO_TOKEN) { if (!ImpersonateSelf(SecurityImpersonation)) { MessageBox(NULL, "Code: 101", "Starter error", NULL); return 0; } if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){ MessageBox(NULL, "Code: 102", "Starter error", NULL); return 0; } } else return 0; } VMEND if( !SetPrivilege(hToken, SE_DEBUG_NAME, TRUE) ) { MessageBox(NULL, "Code: 103", "Starter error", NULL); CloseHandle(hToken); return 0; } char szCmd[128]; //DWORD dwTICK = ; //DWORD XOR = (DWORD)time(NULL); //dwTICK ^= XOR; sprintf(szCmd, "main.exe -test -k%d", GetTickCount()); if( !CreateProcess( NULL, // No module name (use command line) szCmd, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { MessageBox(NULL, "Code: 104", "Starter error", NULL); return 0; } try { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pi.dwProcessId); if( !hProcess ) { MessageBox(NULL, "Code: 105", "Starter error", NULL); return 0; } HANDLE hMainThread = OpenThread(THREAD_ALL_ACCESS,FALSE,pi.dwThreadId); if( !hMainThread ) { MessageBox(NULL, "Code: 106", "Starter error", NULL); return 0; } VMBEGIN DWORD lOfs; BYTE jmp[2] = {0xEB,0xFE}; BYTE original[2] = {0x60,0x9C}; ReadProcessMemory(hProcess,(LPVOID)MAIN_EIP,original,2,&lOfs); WriteProcessMemory(hProcess,(LPVOID)MAIN_EIP,jmp,2,&lOfs); ResumeThread(hMainThread); CONTEXT context; for(int i = 0; i < 50 && context.Eip != MAIN_EIP; i++) { Sleep(100); // read the thread context context.ContextFlags = CONTEXT_CONTROL; GetThreadContext( hMainThread, &context ); } if( context.Eip != MAIN_EIP ) { MessageBox(NULL, "Code: 107", "Starter error", NULL); return 0; } HANDLE hThread; char szLibPath[_MAX_PATH] = { "zClient.dll" }; void* pLibRemote; HMODULE hKernel32 = ::GetModuleHandle("Kernel32"); pLibRemote = ::VirtualAllocEx( hProcess, NULL, sizeof(szLibPath),MEM_COMMIT, PAGE_READWRITE );::WriteProcessMemory( hProcess, pLibRemote, (void*)szLibPath,sizeof(szLibPath), NULL ); hThread = ::CreateRemoteThread( hProcess, NULL, 0,(LPTHREAD_START_ROUTINE) ::GetProcAddress( hKernel32,"LoadLibraryA" ),pLibRemote, 0, NULL ); ::WaitForSingleObject( hThread, INFINITE ); SuspendThread(hMainThread); WriteProcessMemory(hProcess,(LPVOID)MAIN_EIP,original,2,&lOfs); ResumeThread(hMainThread); CloseHandle(hProcess); CloseHandle(hMainThread); VMEND } catch( ... ) { } return true; }
int winAccessW(const wchar_t *path, int mode) { DWORD attr = GetFileAttributesW(path); if(attr == 0xffffffff) return -1; if(mode == F_OK) return 0; if(mode & X_OK) if(!(attr & FILE_ATTRIBUTE_DIRECTORY)) { /* Directory, so OK */ /* Look at extension for executables */ wchar_t *p = wcsrchr(path, '.'); if(p == NULL || !((wcsicmp(p, L".exe") == 0) || (wcsicmp(p, L".com") == 0) || (wcsicmp(p, L".bat") == 0) || (wcsicmp(p, L".cmd") == 0)) ) return -1; } { /* Now look for file security info */ SECURITY_DESCRIPTOR *sdPtr = NULL; DWORD size = 0; GENERIC_MAPPING genMap; HANDLE hToken = NULL; DWORD desiredAccess = 0; DWORD grantedAccess = 0; BOOL accessYesNo = FALSE; PRIVILEGE_SET privSet; DWORD privSetSize = sizeof(PRIVILEGE_SET); int error; /* get size */ GetFileSecurityW(path, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 0, 0, &size); error = GetLastError(); if (error != ERROR_INSUFFICIENT_BUFFER) return -1; sdPtr = (SECURITY_DESCRIPTOR *) alloca(size); if(!GetFileSecurityW(path, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, sdPtr, size, &size)) return -1; /* * Perform security impersonation of the user and open the * resulting thread token. */ if(!ImpersonateSelf(SecurityImpersonation)) return -1; if(!OpenThreadToken(GetCurrentThread (), TOKEN_DUPLICATE | TOKEN_QUERY, FALSE, &hToken)) return -1; if (mode & R_OK) desiredAccess |= FILE_GENERIC_READ; if (mode & W_OK) desiredAccess |= FILE_GENERIC_WRITE; if (mode & X_OK) desiredAccess |= FILE_GENERIC_EXECUTE; memset(&genMap, 0x0, sizeof (GENERIC_MAPPING)); genMap.GenericRead = FILE_GENERIC_READ; genMap.GenericWrite = FILE_GENERIC_WRITE; genMap.GenericExecute = FILE_GENERIC_EXECUTE; genMap.GenericAll = FILE_ALL_ACCESS; if(!AccessCheck(sdPtr, hToken, desiredAccess, &genMap, &privSet, &privSetSize, &grantedAccess, &accessYesNo)) { CloseHandle(hToken); return -1; } CloseHandle(hToken); if (!accessYesNo) return -1; if ((mode & W_OK) && !(attr & FILE_ATTRIBUTE_DIRECTORY) && (attr & FILE_ATTRIBUTE_READONLY)) return -1; } return 0; }
// Write hook static bool writeHook(GHOOK *h) { if(h->active) return true; // Already hooked //dbg("Hooking %s/%s", h->dll, h->name); memset(h->stub, 0x90, STUBLEN+JMPDATALEN); // Fill stub function with NOP // Load library & get proc address HINSTANCE hLib = GetModuleHandle(h->dll); if(!hLib) { dbg("Module not loaded"); return false; } //h->funcOrig = (ULONG_PTR*) GetProcAddress((HMODULE) hLib, h->name); h->funcOrig = (ULONG_PTR) GetProcAddress((HMODULE) hLib, h->name); if(!h->funcOrig) { dbg("Export not found in DLL!"); return false; } // Walk instructions from beginning of function to find stub data size & stub jmp pos BYTE *sJmp = instructionCount((BYTE*) h->funcOrig, 5); DWORD slen = (DWORD) (sJmp - (BYTE*)h->funcOrig);// Stub length (without jmp) h->stublen = slen; // Open handle to current process HANDLE hSelf = NULL; hSelf = OpenProcess(PROCESS_VM_WRITE|PROCESS_VM_OPERATION, FALSE, GetCurrentProcessId()); if(!hSelf) { // Openprocess failed, attempt debug access HANDLE hToken; if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, FALSE, &hToken)) { ImpersonateSelf(SecurityImpersonation); OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, FALSE, &hToken); } if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)) { // Debug access failed, propably non-admin user dbg("writeHook: SetPrivilege failed - Check user permissions"); return false; // This isn't going to work } else { // Hey, it worked! Try again... hSelf = OpenProcess(PROCESS_VM_WRITE|PROCESS_VM_OPERATION, FALSE, GetCurrentProcessId()); if(!hSelf) { dbg("OpenProcess failed"); return false; } } } // Create stub code, copy data from function start & append jmp memcpy(h->stub, (void*)h->funcOrig, slen); writeJmpOpcode(hSelf, h->stub+slen, (void*) (h->funcOrig+slen)); if(h->stub[0] == 0xE9) { // 0xE9 = jmp instruction // JMP at beginning of previous hook code, must change the offset or it will jump to wrong location // New correct position is: jump address + original function pointer - stub function pointer ULONG_PTR *jp = (ULONG_PTR*) (h->stub+1); ULONG_PTR newjp = *jp + ((BYTE*)h->funcOrig - (BYTE*)h->stub); dbg("Existing hook detected at %s/%s, redirecting JMP (0x%08X -> 0x%08X)", h->dll, h->name, *jp, newjp); *jp = newjp; } // Mark stub code executable DWORD oldprot = NULL; VirtualProtectEx(hSelf, h->stub, STUBLEN+JMPDATALEN, PAGE_EXECUTE_READWRITE, &oldprot); // Write jmp to beginning of original function writeJmpOpcode(hSelf, (void*)h->funcOrig, (void*) h->funcOver); CloseHandle(hSelf); //FreeLibrary(hLib); dbg("Hooked %s/%s", h->dll, h->name); h->active = true; return true; }
//********************************************************************** // // FUNCTION: IsAdmin - This function checks the token of the // calling thread to see if the caller belongs to // the Administrators group. // // PARAMETERS: none // // RETURN VALUE: TRUE if the caller is an administrator on the local // machine. Otherwise, FALSE. // //********************************************************************** BOOL IsAdmin(void) { HANDLE hToken; DWORD dwStatus; DWORD dwAccessMask; DWORD dwAccessDesired; DWORD dwACLSize; DWORD dwStructureSize = sizeof(PRIVILEGE_SET); PACL pACL = NULL; PSID psidAdmin = NULL; BOOL bReturn = FALSE; PRIVILEGE_SET ps; GENERIC_MAPPING GenericMapping; PSECURITY_DESCRIPTOR psdAdmin = NULL; SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; __try { // AccessCheck() requires an impersonation token. ImpersonateSelf(SecurityImpersonation); if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)) { if (GetLastError() != ERROR_NO_TOKEN) __leave; // If the thread does not have an access token, we'll // examine the access token associated with the process. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) __leave; } if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) __leave; psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (psdAdmin == NULL) __leave; if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION)) __leave; // Compute size needed for the ACL. dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD); // Allocate memory for ACL. pACL = (PACL)LocalAlloc(LPTR, dwACLSize); if (pACL == NULL) __leave; // Initialize the new ACL. if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2)) __leave; dwAccessMask = ACCESS_READ | ACCESS_WRITE; // Add the access-allowed ACE to the DACL. if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin)) __leave; // Set the DACL to the SD. if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) __leave; // AccessCheck is sensitive about what is in the SD; set // the group and owner. SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE); SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE); if (!IsValidSecurityDescriptor(psdAdmin)) __leave; dwAccessDesired = ACCESS_READ; // // Initialize GenericMapping structure even though you // do not use generic rights. // GenericMapping.GenericRead = ACCESS_READ; GenericMapping.GenericWrite = ACCESS_WRITE; GenericMapping.GenericExecute = 0; GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE; if (!AccessCheck(psdAdmin, hToken, dwAccessDesired, &GenericMapping, &ps, &dwStructureSize, &dwStatus, &bReturn)) { printf("AccessCheck() failed with error %lu\n", GetLastError()); __leave; } RevertToSelf(); } __finally { // Clean up. if (pACL) LocalFree(pACL); if (psdAdmin) LocalFree(psdAdmin); if (psidAdmin) FreeSid(psidAdmin); } return bReturn; }