unsigned int TscThreadExecutor::multi_thread(ThreadProc threadProc) { TSC_THREAD *threadHandles = new TSC_THREAD[_settings._jobs]; TSC_LOCK_INIT(&_fileSync); TSC_LOCK_INIT(&_errorSync); TSC_LOCK_INIT(&_reportSync); #ifdef TSC_THREADING_MODEL_WIN for (unsigned int i = 0; i < _settings._jobs; ++i) { threadHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadProc, this, 0, NULL); if (!threadHandles[i]) { std::cerr << "#### .\nTscThreadExecutor::check error, errno :" << errno << std::endl; exit(EXIT_FAILURE); } } DWORD waitResult = WaitForMultipleObjects(_settings._jobs, threadHandles, TRUE, INFINITE); if (waitResult != WAIT_OBJECT_0) { if (waitResult == WAIT_FAILED) { std::cerr << "#### .\nTscThreadExecutor::check wait failed, result: " << waitResult << " error: " << GetLastError() << std::endl; exit(EXIT_FAILURE); } else { std::cerr << "#### .\nTscThreadExecutor::check wait failed, result: " << waitResult << std::endl; exit(EXIT_FAILURE); } } unsigned int result = 0; for (unsigned int i = 0; i < _settings._jobs; ++i) { DWORD exitCode; if (!GetExitCodeThread(threadHandles[i], &exitCode)) { std::cerr << "#### .\nTscThreadExecutor::check get exit code failed, error:" << GetLastError() << std::endl; exit(EXIT_FAILURE); } result += exitCode; if (!CloseHandle(threadHandles[i])) { std::cerr << "#### .\nTscThreadExecutor::check close handle failed, error:" << GetLastError() << std::endl; exit(EXIT_FAILURE); } } #else for (unsigned int i = 0; i < _settings._jobs; ++i) { int ret = pthread_create(&threadHandles[i], nullptr, threadProc, this); if (ret) { std::cerr << "#### .\nTscThreadExecutor::check error, errno :" << ret << std::endl; exit(EXIT_FAILURE); } } unsigned int result = 0; void* tret = nullptr; for (int i = 0; i < _settings._jobs; ++i) { int ret = pthread_join(threadHandles[i], &tret); if (ret) { std::cerr << "#### .\nTscThreadExecutor::check get exit code failed, error:" << ret << std::endl; exit(EXIT_FAILURE); } result += (unsigned int)(intptr_t)(tret); } #endif TSC_LOCK_DELETE(&_fileSync); TSC_LOCK_DELETE(&_errorSync); TSC_LOCK_DELETE(&_reportSync); delete[] threadHandles; return result; }
LRESULT CALLBACK WndProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { HDC hdc; LPDCB lpDCB = &cc.dcb; static int cxClient,cyClient; PAINTSTRUCT ps; static int iVertPos = 0; SCROLLINFO si; char buffer[128] = {0}; DWORD bytesRead; DWORD bytesWritten; //OVERLAPPED ov = {0,0,0}; std::fstream ifs; OPENFILENAME ofn; static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ; static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH] ; char packet[1024]; char packet2[2]; if (cxClient && cyClient) { /*text_area.left = 0; text_area.top = 0; text_area.right = cxClient; text_area.bottom = cyClient; areaset = true;*/ topright.left = cxClient - cxClient/3 + 1; topright.top = 1; topright.right = cxClient; topright.bottom = cyClient - cyClient/3 - 1; topleft.left = 1; topleft.top = 1; topleft.right = cxClient - cxClient/3 - 1; topleft.bottom = cyClient - cyClient/3 - 1; } switch (Message) { case WM_CREATE: ov.Offset = 0; ov.OffsetHigh = 0; ov.Pointer = 0; ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); semm = CreateSemaphore(NULL, 0, 1, NULL); global.hSem = &semm; InitializeCriticalSection(§ion); break; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_COM1: cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; if (!CommConfigDialog (lpszCommName1, hwnd, &cc)) break; else { comset = true; curCom = 1; } break; case IDM_COM2: cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; if (!CommConfigDialog (lpszCommName2, hwnd, &cc)) break; else { comset = true; curCom = 2; } break; case IDM_COM3: cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; if (!CommConfigDialog (lpszCommName3, hwnd, &cc)) break; else { comset = true; curCom = 3; } break; case IDM_COM4: cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; if (!CommConfigDialog (lpszCommName4, hwnd, &cc)) { break; }else { comset = true; curCom = 4; } break; case IDM_Connect: //WaitForSingleObject(ov.hEvent, INFINITE); //MessageBox(hwnd, TEXT(""), TEXT(""), MB_OK); if (comset) { if (curCom == 1) { if ((hComm = CreateFile (lpszCommName1, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE) { MessageBox (NULL, TEXT("Error opening COM port:"), TEXT(""), MB_OK); return FALSE; } } else if (curCom == 2) { if ((hComm = CreateFile (lpszCommName2, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL)) == INVALID_HANDLE_VALUE) { MessageBox (NULL, TEXT("Error opening COM port:"), TEXT(""), MB_OK); return FALSE; } } else if (curCom == 3) { if ((hComm = CreateFile (lpszCommName3, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL)) == INVALID_HANDLE_VALUE) { MessageBox (NULL, TEXT("Error opening COM port:"), TEXT(""), MB_OK); return FALSE; } } else if (curCom == 4) { if ((hComm = CreateFile (lpszCommName4, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE) { MessageBox (NULL, TEXT("Error opening COM port:"), TEXT(""), MB_OK); return FALSE; } } lpDCB = &cc.dcb; if (!SetCommState(hComm, lpDCB)) { MessageBox (NULL, TEXT("Error setting COM state"), TEXT(""), MB_OK); return false; } COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (!SetCommTimeouts(hComm, &timeouts)) { MessageBox (NULL, TEXT("Error setting COM timeouts"), TEXT(""), MB_OK); return false; } if (hComm) { global.hComm = &hComm; global.ov = ov; //opThrd = CreateThread(NULL, 0, OutputThread, (LPVOID)hwnd, 0, &opThrdID ); recvThread = CreateThread(NULL, 0, receiverThread, &global, NULL, &opThrdID); MessageBox(NULL, TEXT("connected"), TEXT(""), MB_OK); } else { MessageBox(NULL, TEXT("Please select a COM port."), TEXT(""), MB_OK); } } else { MessageBox(NULL, TEXT("Please select a COM port."), TEXT(""), MB_OK); } break; case IDM_Disconnect: //kills the reading thread and closes the com port if they are active if (KillReader == false && hComm) { KillReader = true; CloseHandle(hComm); MessageBox(NULL, TEXT("disconnected"), TEXT(""), MB_OK); } break; case IDM_OpenFile: ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = NULL ; // Set in Open and Close functions ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = NULL ; // Set in Open and Close functions ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = 0 ; // Set in Open and Close functions ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("txt") ; ofn.lCustData = 0L ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; ofn.hwndOwner = hwnd ; ofn.lpstrFile = szFileName ; ofn.lpstrFileTitle = szTitleName ; ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT ; if (GetOpenFileName(&ofn)) { std::wstring wfilename(szFileName); std::string filename; for(int i = 0; i < wfilename.size(); i++) { filename += wfilename[i]; } ifs = OpenFile(filename); readFile(ifs); DWORD threadID; DWORD exitStatus; if (sendThread == 0 || (GetExitCodeThread(sendThread, &exitStatus) && exitStatus != STILL_ACTIVE)) { sendThread = CreateThread(NULL, 0, sendBufferThread, &global, NULL, &threadID); } } } break; case WM_CHAR: // Process keystroke break; case WM_LBUTTONDOWN: break; case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); si.cbSize = sizeof(si); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = cyClient; si.nPos = 0; si.nPage = 50; SetScrollInfo(hwnd, SB_VERT, &si, TRUE); break; case WM_VSCROLL: si.cbSize = sizeof(si); si.fMask = SIF_ALL; GetScrollInfo(hwnd, SB_VERT, &si); iVertPos = si.nPos; switch(LOWORD(wParam)){ case SB_LINEUP: si.nPos -= 10; break; case SB_LINEDOWN: si.nPos += 10; break; case SB_PAGEUP: si.nPos -= si.nPage; break; case SB_PAGEDOWN: si.nPos += si.nPage; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; default: break; } si.fMask = SIF_POS; SetScrollInfo(hwnd, SB_VERT, &si, TRUE); GetScrollInfo(hwnd, SB_VERT, &si); //if there was change in the vertical scroll bar, make adjustments to redraw if (si.nPos != iVertPos){ //InvalidateRect(hwnd, &text_area, TRUE); } break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); MoveToEx(hdc, cxClient - cxClient/3, 0, NULL); LineTo(hdc, cxClient - cxClient/3, cyClient); MoveToEx(hdc, 0, cyClient - cyClient/3, NULL); LineTo(hdc, cxClient, cyClient - cyClient/3); DisplayStatistics(topright, stats, hdc); //DisplayReceivedFileData(topleft, file, hdc); ReleaseDC(hwnd, hdc); break; case WM_DESTROY: // Terminate program if (hComm) { CloseHandle(hComm); } PostQuitMessage (0); break; default: return DefWindowProc (hwnd, Message, wParam, lParam); } return 0; }
VOID IN_PROCESS_APPLICATION::ShutDownInternal() { DWORD dwThreadStatus = 0; DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS(); HANDLE handle = NULL; WIN32_FIND_DATA fileData; if (IsDebuggerPresent()) { dwTimeout = INFINITE; } if (m_fShutdownCalledFromNative || m_status == APPLICATION_STATUS::STARTING || m_status == APPLICATION_STATUS::FAIL) { return; } { SRWLockWrapper lock(m_srwLock); if (m_fShutdownCalledFromNative || m_status == APPLICATION_STATUS::STARTING || m_status == APPLICATION_STATUS::FAIL) { return; } // We need to keep track of when both managed and native initiate shutdown // to avoid AVs. If shutdown has already been initiated in managed, we don't want to call into // managed. We still need to wait on main exiting no matter what. m_fShutdownCalledFromNative // is used for detecting redundant calls and blocking more requests to OnExecuteRequestHandler. m_fShutdownCalledFromNative = TRUE; m_status = APPLICATION_STATUS::SHUTDOWN; if (!m_fShutdownCalledFromManaged) { // We cannot call into managed if the dll is detaching from the process. // Calling into managed code when the dll is detaching is strictly a bad idea, // and usually results in an AV saying "The string binding is invalid" if (!g_fProcessDetach) { m_ShutdownHandler(m_ShutdownHandlerContext); m_ShutdownHandler = NULL; } } // Release the lock before we wait on the thread to exit. } if (!m_fShutdownCalledFromManaged) { if (m_hThread != NULL && GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE) { // wait for graceful shutdown, i.e., the exit of the background thread or timeout if (WaitForSingleObject(m_hThread, dwTimeout) != WAIT_OBJECT_0) { // if the thread is still running, we need kill it first before exit to avoid AV if (GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE) { // Calling back into managed at this point is prone to have AVs // Calling terminate thread here may be our best solution. TerminateThread(m_hThread, STATUS_CONTROL_C_EXIT); } } } } CloseHandle(m_hThread); m_hThread = NULL; s_Application = NULL; CloseStdErrHandles(); if (m_pStdFile != NULL) { fflush(stdout); fflush(stderr); fclose(m_pStdFile); } if (m_hLogFileHandle != INVALID_HANDLE_VALUE) { m_Timer.CancelTimer(); CloseHandle(m_hLogFileHandle); m_hLogFileHandle = INVALID_HANDLE_VALUE; } // delete empty log file handle = FindFirstFile(m_struLogFilePath.QueryStr(), &fileData); if (handle != INVALID_HANDLE_VALUE && fileData.nFileSizeHigh == 0 && fileData.nFileSizeLow == 0) // skip check of nFileSizeHigh { FindClose(handle); // no need to check whether the deletion succeeds // as nothing can be done DeleteFile(m_struLogFilePath.QueryStr()); } }
int hook_enable() { // Lock the thread control mutex. This will be unlocked when the // thread has finished starting, or when it has fully stopped. #ifdef _WIN32 WaitForSingleObject(hook_control_mutex, INFINITE); #else pthread_mutex_lock(&hook_control_mutex); #endif // Set the initial status. int status = UIOHOOK_FAILURE; #ifndef _WIN32 // Create the thread attribute. pthread_attr_t hook_thread_attr; pthread_attr_init(&hook_thread_attr); // Get the policy and priority for the thread attr. int policy; pthread_attr_getschedpolicy(&hook_thread_attr, &policy); int priority = sched_get_priority_max(policy); #endif #if defined(_WIN32) DWORD hook_thread_id; DWORD *hook_thread_status = malloc(sizeof(DWORD)); hook_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) hook_thread_proc, hook_thread_status, 0, &hook_thread_id); if (hook_thread != INVALID_HANDLE_VALUE) { #else int *hook_thread_status = malloc(sizeof(int)); if (pthread_create(&hook_thread, &hook_thread_attr, hook_thread_proc, hook_thread_status) == 0) { #endif #if defined(_WIN32) // Attempt to set the thread priority to time critical. if (SetThreadPriority(hook_thread, THREAD_PRIORITY_TIME_CRITICAL) == 0) { logger_proc(LOG_LEVEL_WARN, "%s [%u]: Could not set thread priority %li for thread %#p! (%#lX)\n", __FUNCTION__, __LINE__, (long) THREAD_PRIORITY_TIME_CRITICAL, hook_thread , (unsigned long) GetLastError()); } #elif (defined(__APPLE__) && defined(__MACH__)) || _POSIX_C_SOURCE >= 200112L // Some POSIX revisions do not support pthread_setschedprio so we will // use pthread_setschedparam instead. struct sched_param param = { .sched_priority = priority }; if (pthread_setschedparam(hook_thread, SCHED_OTHER, ¶m) != 0) { logger_proc(LOG_LEVEL_WARN, "%s [%u]: Could not set thread priority %i for thread 0x%lX!\n", __FUNCTION__, __LINE__, priority, (unsigned long) hook_thread); } #else // Raise the thread priority using glibc pthread_setschedprio. if (pthread_setschedprio(hook_thread, priority) != 0) { logger_proc(LOG_LEVEL_WARN, "%s [%u]: Could not set thread priority %i for thread 0x%lX!\n", __FUNCTION__, __LINE__, priority, (unsigned long) hook_thread); } #endif // Wait for the thread to indicate that it has passed the // initialization portion by blocking until either a EVENT_HOOK_ENABLED // event is received or the thread terminates. // NOTE This unlocks the hook_control_mutex while we wait. #ifdef _WIN32 WaitForSingleObject(hook_control_cond, INFINITE); #else pthread_cond_wait(&hook_control_cond, &hook_control_mutex); #endif #ifdef _WIN32 if (WaitForSingleObject(hook_running_mutex, 0) != WAIT_TIMEOUT) { #else if (pthread_mutex_trylock(&hook_running_mutex) == 0) { #endif // Lock Successful; The hook is not running but the hook_control_cond // was signaled! This indicates that there was a startup problem! // Get the status back from the thread. #ifdef _WIN32 WaitForSingleObject(hook_thread, INFINITE); GetExitCodeThread(hook_thread, hook_thread_status); #else pthread_join(hook_thread, (void **) &hook_thread_status); status = *hook_thread_status; #endif } else { // Lock Failure; The hook is currently running and wait was signaled // indicating that we have passed all possible start checks. We can // always assume a successful startup at this point. status = UIOHOOK_SUCCESS; } free(hook_thread_status); logger_proc(LOG_LEVEL_DEBUG, "%s [%u]: Thread Result: (%#X).\n", __FUNCTION__, __LINE__, status); } else { status = UIOHOOK_ERROR_THREAD_CREATE; } // Make sure the control mutex is unlocked. #ifdef _WIN32 ReleaseMutex(hook_control_mutex); #else pthread_mutex_unlock(&hook_control_mutex); #endif return status; } int main() { // Lock the thread control mutex. This will be unlocked when the // thread has finished starting, or when it has fully stopped. #ifdef _WIN32 // Create event handles for the thread hook. hook_running_mutex = CreateMutex(NULL, FALSE, TEXT("hook_running_mutex")); hook_control_mutex = CreateMutex(NULL, FALSE, TEXT("hook_control_mutex")); hook_control_cond = CreateEvent(NULL, TRUE, FALSE, TEXT("hook_control_cond")); #else pthread_mutex_init(&hook_running_mutex, NULL); pthread_mutex_init(&hook_control_mutex, NULL); pthread_cond_init(&hook_control_cond, NULL); #endif // Set the logger callback for library output. hook_set_logger_proc(&logger_proc); // Set the event callback for uiohook events. hook_set_dispatch_proc(&dispatch_proc); // Start the hook and block. // NOTE If EVENT_HOOK_ENABLED was delivered, the status will always succeed. int status = hook_enable(); switch (status) { case UIOHOOK_SUCCESS: // We no longer block, so we need to explicitly wait for the thread to die. #ifdef _WIN32 WaitForSingleObject(hook_thread, INFINITE); #else #if defined(__APPLE__) && defined(__MACH__) // NOTE Darwin requires that you start your own runloop from main. CFRunLoopRun(); #endif pthread_join(hook_thread, NULL); #endif break; // System level errors. case UIOHOOK_ERROR_OUT_OF_MEMORY: logger_proc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)\n", status); break; // X11 specific errors. case UIOHOOK_ERROR_X_OPEN_DISPLAY: logger_proc(LOG_LEVEL_ERROR, "Failed to open X11 display. (%#X)\n", status); break; case UIOHOOK_ERROR_X_RECORD_NOT_FOUND: logger_proc(LOG_LEVEL_ERROR, "Unable to locate XRecord extension. (%#X)\n", status); break; case UIOHOOK_ERROR_X_RECORD_ALLOC_RANGE: logger_proc(LOG_LEVEL_ERROR, "Unable to allocate XRecord range. (%#X)\n", status); break; case UIOHOOK_ERROR_X_RECORD_CREATE_CONTEXT: logger_proc(LOG_LEVEL_ERROR, "Unable to allocate XRecord context. (%#X)\n", status); break; case UIOHOOK_ERROR_X_RECORD_ENABLE_CONTEXT: logger_proc(LOG_LEVEL_ERROR, "Failed to enable XRecord context. (%#X)\n", status); break; // Windows specific errors. case UIOHOOK_ERROR_SET_WINDOWS_HOOK_EX: logger_proc(LOG_LEVEL_ERROR, "Failed to register low level windows hook. (%#X)\n", status); break; // Darwin specific errors. case UIOHOOK_ERROR_AXAPI_DISABLED: logger_proc(LOG_LEVEL_ERROR, "Failed to enable access for assistive devices. (%#X)\n", status); break; case UIOHOOK_ERROR_CREATE_EVENT_PORT: logger_proc(LOG_LEVEL_ERROR, "Failed to create apple event port. (%#X)\n", status); break; case UIOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE: logger_proc(LOG_LEVEL_ERROR, "Failed to create apple run loop source. (%#X)\n", status); break; case UIOHOOK_ERROR_GET_RUNLOOP: logger_proc(LOG_LEVEL_ERROR, "Failed to acquire apple run loop. (%#X)\n", status); break; case UIOHOOK_ERROR_CREATE_OBSERVER: logger_proc(LOG_LEVEL_ERROR, "Failed to create apple run loop observer. (%#X)\n", status); break; // Default error. case UIOHOOK_FAILURE: default: logger_proc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)\n", status); break; } #ifdef _WIN32 // Create event handles for the thread hook. CloseHandle(hook_thread); CloseHandle(hook_running_mutex); CloseHandle(hook_control_mutex); CloseHandle(hook_control_cond); #else pthread_mutex_destroy(&hook_running_mutex); pthread_mutex_destroy(&hook_control_mutex); pthread_cond_destroy(&hook_control_cond); #endif return status; }
BOOL CheckThreads(__in DWORD ProcId) /*++ Routine Description: Enumerates all threads (or optionally only threads for one process) in the system. It the calls the WCT API on each of them. Arguments: ProcId--Specifies the process ID to analyze. If '0' all processes in the system will be checked. Return Value: TRUE if processes could be checked; FALSE if a general failure occurred. --*/ { DWORD processes[1024]; DWORD numProcesses; DWORD i; // Try to enable the SE_DEBUG_NAME privilege for this process. // Continue even if this fails--we just won't be able to retrieve // wait chains for processes not owned by the current user. if (!GrantDebugPrivilege()) { printf("Could not enable the debug privilege"); } // Get a list of all processes currently running. if (EnumProcesses(processes, sizeof(processes), &numProcesses) == FALSE) { printf("Could not enumerate processes"); return FALSE; } for (i = 0; i < numProcesses / sizeof(DWORD); i++) { HANDLE process; HANDLE snapshot; if (processes[i] == GetCurrentProcessId()) { continue; } // If the caller specified a Process ID, check if we have a match. if (ProcId != 0) { if (processes[i] != ProcId) { continue; } } // Get a handle to this process. process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processes[i]); if (process) { WCHAR file[MAX_PATH]; printf("Process 0x%x - ", processes[i]); // Retrieve the executable name and print it. if (GetProcessImageFileName(process, file, ARRAYSIZE(file)) > 0) { PCWSTR filePart = wcsrchr(file, L'\\'); if (filePart) { filePart++; } else { filePart = file; } printf("%S", filePart); } printf("\n----------------------------------\n"); // Get a snapshot of this process. This enables us to // enumerate its threads. snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, processes[i]); if (snapshot) { THREADENTRY32 thread; thread.dwSize = sizeof(thread); // Walk the thread list and print each wait chain if (Thread32First(snapshot, &thread)) { do { if (thread.th32OwnerProcessID == processes[i]) { // Open a handle to this specific thread HANDLE threadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread.th32ThreadID); if (threadHandle) { // Check whether the thread is still running DWORD exitCode; GetExitCodeThread(threadHandle, &exitCode); if (exitCode == STILL_ACTIVE) { // Print the wait chain. PrintWaitChain(thread.th32ThreadID); } CloseHandle(threadHandle); } } } while (Thread32Next(snapshot, &thread)); } CloseHandle(snapshot); } CloseHandle(process); printf("\n"); } } return TRUE; }
/// <summary> /// Process Kinect window menu commands /// </summary> /// <param name="commanId">ID of the menu item</param> /// <param name="param">Parameter passed in along with the commmand ID</param> /// <param name="previouslyChecked">Check status of menu item before command is issued</param> void KinectSettings::ProcessMenuCommand(WORD commandId, WORD param, bool previouslyChecked) { DWORD ExitCode; FaceTracker* pFaceTracker; InbedAPPs* pFallDetect; DepthInbedAPPs* pDepthInbedApps; LegRaisExcer* pLegRaisExer; HandRaisExcer* pHandRaisExer; m_pKinectWindow->GetFaceTraker(&pFaceTracker); m_pPrimaryView->GetFallDetect(&pFallDetect); m_pDepthStream->GetDepthInbedAPPs(&pDepthInbedApps); m_pPrimaryView->GetLegRaisExcer(&pLegRaisExer); m_pPrimaryView->GetHandRaisExcer(&pHandRaisExer); if (ID_COLORSTREAM_PAUSE == commandId) { // Pause color stream if (m_pColorStream) { m_pColorStream->PauseStream(!previouslyChecked); } } else if (ID_COLORSTREAM_RESOLUTION_START <= commandId && ID_COLORSTREAM_RESOLUTION_END >= commandId) { // Set color stream format and resolution if (!m_pColorStream) { return; } switch (commandId) { case ID_RESOLUTION_RGBRESOLUTION640X480FPS30: m_pColorStream->SetImageType(NUI_IMAGE_TYPE_COLOR); m_pColorStream->SetImageResolution(NUI_IMAGE_RESOLUTION_640x480); break; case ID_RESOLUTION_RGBRESOLUTION1280X960FPS12: m_pColorStream->SetImageType(NUI_IMAGE_TYPE_COLOR); m_pColorStream->SetImageResolution(NUI_IMAGE_RESOLUTION_1280x960); break; case ID_RESOLUTION_YUVRESOLUTION640X480FPS15: m_pColorStream->SetImageType(NUI_IMAGE_TYPE_COLOR_YUV); m_pColorStream->SetImageResolution(NUI_IMAGE_RESOLUTION_640x480); break; case ID_RESOLUTION_INFRAREDRESOLUTION640X480FPS30: m_pColorStream->SetImageType(NUI_IMAGE_TYPE_COLOR_INFRARED); m_pColorStream->SetImageResolution(NUI_IMAGE_RESOLUTION_640x480); break; case ID_RESOLUTION_RAWBAYERRESOLUTION640X480FPS30: m_pColorStream->SetImageType(NUI_IMAGE_TYPE_COLOR_RAW_BAYER); m_pColorStream->SetImageResolution(NUI_IMAGE_RESOLUTION_640x480); break; case ID_RESOLUTION_RAWBAYERRESOLUTION1280X960FPS12: m_pColorStream->SetImageType(NUI_IMAGE_TYPE_COLOR_RAW_BAYER); m_pColorStream->SetImageResolution(NUI_IMAGE_RESOLUTION_1280x960); break; default: return; } m_pColorStream->OpenStream(); } else if (ID_DEPTHSTREAM_PAUSE == commandId) { // Pause depth stream if(m_pDepthStream) { m_pDepthStream->PauseStream(!previouslyChecked); } } else if (ID_DEPTHSTREAM_RANGEMODE_START <= commandId && ID_DEPTHSTREAM_RANGEMODE_END >= commandId) { // Set depth stream range mode bool nearMode = false; switch (commandId) { case ID_RANGEMODE_DEFAULT: nearMode = false; break; case ID_RANGEMODE_NEAR: nearMode = true; break; default: return; } if (m_pDepthStream) { m_pDepthStream->SetNearMode(nearMode); } if (m_pSkeletonStream) { m_pSkeletonStream->SetNearMode(nearMode); } } else if (ID_DEPTHSTREAM_RESOLUTION_START <= commandId && ID_DEPTHSTREAM_RESOLUTION_END >= commandId) { // Set depth stream resolution NUI_IMAGE_RESOLUTION resolution = (NUI_IMAGE_RESOLUTION)(commandId - ID_DEPTHSTREAM_RESOLUTION_START); if (m_pDepthStream) { m_pDepthStream->OpenStream(resolution); } } else if (ID_DEPTHSTREAM_DEPTHTREATMENT_START <= commandId && ID_DEPTHSTREAM_DEPTHTREATMENT_END >= commandId) { // Set depth stream treatment mode DEPTH_TREATMENT treatment = (DEPTH_TREATMENT)(commandId - ID_DEPTHSTREAM_DEPTHTREATMENT_START); if (m_pDepthStream) { m_pDepthStream->SetDepthTreatment(treatment); } } else if (ID_SKELETONSTREAM_PAUSE == commandId) { // Pause skeleton stream if (m_pSkeletonStream) { m_pSkeletonStream->PauseStream(!previouslyChecked); } } else if (ID_SKELETONSTREAM_TRACKINGMODE_START <= commandId && ID_SKELETONSTREAM_TRACKINGMODE_END >= commandId) { // Set skeleton track mode if (!m_pSkeletonStream) { return; } switch (commandId) { case ID_TRACKINGMODE_DEFAULT: m_pSkeletonStream->SetSeatedMode(false); break; case ID_TRACKINGMODE_SEATED: m_pSkeletonStream->SetSeatedMode(true); break; default: return; } } else if (ID_SKELETONSTREAM_CHOOSERMODE_START <= commandId && ID_SKELETONSTREAM_CHOOSERMODE_END >= commandId) { // Set skeleton chooser mode if(!m_pSkeletonStream) { return; } m_pSkeletonStream->SetChooserMode(ConvertCommandIdToChooserMode(commandId)); } else { switch (commandId) { // Bring up camera color setting dialog case ID_CAMERA_COLORSETTINGS: m_pColorSettingsView->ShowView(); break; // Bring up camera exposure setting dialog case ID_CAMERA_EXPOSURESETTINGS: m_pExposureSettingsView->ShowView(); break; // Switch the stream display on primary and secondary stream viewers case ID_VIEWS_SWITCH: if (m_pColorStream && m_pDepthStream) { m_pColorStream->SetStreamViewer(m_pDepthStream->SetStreamViewer(m_pColorStream->SetStreamViewer(nullptr))); } break; case ID_FORCE_OFF_IR: m_pNuiSensor->NuiSetForceInfraredEmitterOff(param); break; //////Recording case ID_RECORDING_AUDIO: if (m_pAudioStream && !m_pAudioStream->GetRecordingStauts()) { m_pAudioStream->SetRecordingStatus(true); } else if (m_pAudioStream && m_pAudioStream->GetRecordingStauts()) { m_pAudioStream->m_pWaveWriter->Stop(); delete(m_pAudioStream->m_pWaveWriter); m_pAudioStream->m_pWaveWriter=NULL; m_pAudioStream->SetRecordingStatus(false); } break; case ID_RECORDING_RGB: if (m_pColorStream && !m_pColorStream->GetRecordingStauts()) { m_pColorStream->SetRecordingStatus(true); } else if (m_pColorStream && m_pColorStream->GetRecordingStauts()) { cvReleaseVideoWriter(&m_pColorStream->m_pwriter); m_pColorStream->m_pwriter=nullptr; m_pColorStream->SetRecordingStatus(false); } break; case ID_RECORDING_DEPTH: if (m_pDepthStream && !m_pDepthStream->GetRecordingStauts()) { m_pDepthStream->SetRecordingStatus(true); } else if (m_pDepthStream && m_pDepthStream->GetRecordingStauts()) { cvReleaseVideoWriter(&m_pDepthStream->m_pwriter); m_pDepthStream->m_pwriter=nullptr; m_pDepthStream->SetRecordingStatus(false); } break; case ID_RECORDING_ALL: ////RGB if (m_pColorStream && !m_pColorStream->GetRecordingStauts()) { m_pColorStream->SetRecordingStatus(true); } else if (m_pColorStream && m_pColorStream->GetRecordingStauts()) { cvReleaseVideoWriter(&m_pColorStream->m_pwriter); m_pColorStream->m_pwriter=nullptr; m_pColorStream->SetRecordingStatus(false); } ////Depth if (m_pDepthStream && !m_pDepthStream->GetRecordingStauts()) { m_pDepthStream->SetRecordingStatus(true); } else if (m_pDepthStream && m_pDepthStream->GetRecordingStauts()) { cvReleaseVideoWriter(&m_pDepthStream->m_pwriter); m_pDepthStream->m_pwriter=nullptr; m_pDepthStream->SetRecordingStatus(false); } //////Audio if (m_pAudioStream && !m_pAudioStream->GetRecordingStauts()) { m_pAudioStream->SetRecordingStatus(true); } else if (m_pAudioStream && m_pAudioStream->GetRecordingStauts()) { m_pAudioStream->m_pWaveWriter->Stop(); delete(m_pAudioStream->m_pWaveWriter); m_pAudioStream->m_pWaveWriter=NULL; m_pAudioStream->SetRecordingStatus(false); } break; ////Recording 3D facial model case ID_RECORDING_3DFACIALMODEL: if (!(pFaceTracker->GetFTRecordingStatus())) pFaceTracker->SetFTRecordingStatus(true); else { pFaceTracker->SetFTRecordingStatus(false); pFaceTracker->ResetAUSUcounts(); pFaceTracker->CloseAUSUfile(); } break; ////Speech recognition dication pad case ID_SPEECHRECOGNITION: /*if (!m_threadRun) {*/ //m_hSpeechRecogThread=CreateThread(NULL, 0, m_pKinectWindow->SpeechRecogStaticThread, (PVOID)m_pKinectWindow, 0, 0); //m_threadRun=true; /* } else {*/ //if (m_hSpeechRecogThread) //{ // CSimpleDict* pSimpleDict; // m_pKinectWindow->GetSimpleDict(&pSimpleDict); // pSimpleDict->~CSimpleDict(); // WaitForSingleObject(m_hSpeechRecogThread, 200); // CloseHandle(m_hSpeechRecogThread); // m_threadRun=false; //} //} break; ////In-bed detection case ID_FALLDETECTION: if (!(pFallDetect->getIsRunFallDetect())) { pFallDetect->setIsRunFallDetect(TRUE); if (!m_FallDetectThreadRun) { m_hFallDetectTxt2SpeechThread = CreateThread(NULL, 0, pFallDetect->Txt2SpeechStaticThread, (PVOID)pFallDetect, 0, 0); m_FallDetectThreadRun = TRUE; } } else { pFallDetect->setIsRunFallDetect(FALSE); if (m_FallDetectThreadRun) { DWORD lpExitCode; GetExitCodeThread(m_hFallDetectTxt2SpeechThread, &lpExitCode); TerminateThread(m_hFallDetectTxt2SpeechThread, lpExitCode); WaitForSingleObject(m_hFallDetectTxt2SpeechThread, 200); CloseHandle(m_hFallDetectTxt2SpeechThread); m_FallDetectThreadRun = FALSE; } } break; case ID_MOVEMENTDETECTION: if (!(pFallDetect->getIsRunMovementDetect())) { pFallDetect->setIsRunMovementDetect(TRUE); } else { pFallDetect->setIsRunMovementDetect(FALSE); } break; case ID_OUTOFBEDDETECTION: break; case ID_LYANGLEDETECTION: if (!(pDepthInbedApps->getIsRunLyAngleDetect())) { pDepthInbedApps->setIsRunLyAngleDetect(TRUE); } else { pDepthInbedApps->setIsRunLyAngleDetect(FALSE); } break; case ID_CALLNURSINGBYHANDRAISING: if (!(pFallDetect->getIsRunHandsMovementRIC())) { pFallDetect->setIsRunHandsMovementRIC(TRUE); if (!m_NurseCallThreadRun) { m_hNurseCallTxt2SpeechThread = CreateThread(NULL, 0, m_pPrimaryView->Txt2SpeechStaticThread, (PVOID)m_pPrimaryView, 0, 0); m_NurseCallThreadRun = TRUE; } } else { pFallDetect->setIsRunHandsMovementRIC(FALSE); if (m_NurseCallThreadRun) { DWORD lpExitCode; GetExitCodeThread(m_hNurseCallTxt2SpeechThread, &lpExitCode); TerminateThread(m_hNurseCallTxt2SpeechThread, lpExitCode); WaitForSingleObject(m_hNurseCallTxt2SpeechThread, 200); CloseHandle(m_hNurseCallTxt2SpeechThread); m_NurseCallThreadRun = FALSE; } } break; case ID_VIEWDETECTIONRECS: if (!m_processFlag) { ViewDetectionRes(); m_processFlag = TRUE; } else { GetViewDetecResProcessStatus(&ExitCode); TerminateProcess(m_pi.hProcess, ExitCode); m_processFlag = FALSE; } break; case ID_STANDMOVELEGOUTWARD: if (!(pLegRaisExer->isRunningExcer())) { Sleep(5000); pLegRaisExer->setRunningExer(TRUE); if (!m_LegRaisexcerThreadRun) { m_hLegRaisExcerTxt2SpeechThread = CreateThread(NULL, 0, pLegRaisExer->Txt2SpeechStaticThread, (PVOID)pLegRaisExer, 0, 0); m_LegRaisexcerThreadRun = TRUE; } } else { pLegRaisExer->setRunningExer(FALSE); pLegRaisExer->Reset(); if (m_LegRaisexcerThreadRun) { DWORD lpExitCode; GetExitCodeThread(m_hLegRaisExcerTxt2SpeechThread, &lpExitCode); TerminateThread(m_hLegRaisExcerTxt2SpeechThread, lpExitCode); WaitForSingleObject(m_hLegRaisExcerTxt2SpeechThread, 200); CloseHandle(m_hLegRaisExcerTxt2SpeechThread); m_LegRaisexcerThreadRun = FALSE; } } break; case ID_STANDARMSLIFTWEIGHTS: if (!(pHandRaisExer->isRunningExcer())) { Sleep(5000); pHandRaisExer->setRunningExer(TRUE); if (!m_HandRaisexcerThreadRun) { m_hHandRaisExcerTxt2SpeechThread = CreateThread(NULL, 0, pHandRaisExer->Txt2SpeechStaticThread, (PVOID)pHandRaisExer, 0, 0); m_HandRaisexcerThreadRun = TRUE; } } else { pHandRaisExer->setRunningExer(FALSE); pHandRaisExer->Reset(); if (m_HandRaisexcerThreadRun) { DWORD lpExitCode; GetExitCodeThread(m_hHandRaisExcerTxt2SpeechThread, &lpExitCode); TerminateThread(m_hHandRaisExcerTxt2SpeechThread, lpExitCode); WaitForSingleObject(m_hHandRaisExcerTxt2SpeechThread, 200); CloseHandle(m_hHandRaisExcerTxt2SpeechThread); m_HandRaisexcerThreadRun = FALSE; } } break; default: break; } } }
int InjectCode () { HANDLE hProcess = 0; // Process handle HMODULE hUser32 = 0; // Handle of user32.dll BYTE *pCodeRemote; // Address of InjectFunc() in the remote process. BYTE *pGetSASWndRemote; // Address of GetSASWnd() in the remote process. HANDLE hThread = 0; // The handle and ID of the thread executing DWORD dwThreadId = 0; // the remote InjectFunc(). INJDATA DataLocal; // INJDATA structure BOOL fUnicode; // TRUE if remote process is Unicode int nSuccess = 0; // Subclassing succeded? DWORD dwNumBytesCopied = 0; // Number of bytes written to the remote process. DWORD size; // Calculated function size (= AfterFunc() - Func()) int SearchSize; // SASWindowProc() dummy addr. search size int nDummyOffset; // Offset in SASWindowProc() of dummy addr. BOOL FoundDummyAddr; // Dummy INJDATA reference found in SASWindowProc() ? HWND hSASWnd; // Window handle of Winlogon process BYTE *p; // Enable Debug privilege (needed for some processes) if (!EnablePrivilege(SE_DEBUG_NAME, TRUE)) return 0; // Get handle of "USER32.DLL" hUser32 = GetModuleHandle("user32"); if (!hUser32) return 0; // Get remote process ID PID = GetPIDFromName(szProcessName); if (PID == -1) return 0; // Open remote process hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); if (!hProcess) return 0; __try { // Initialize INJDATA for GetSASWnd() call strcpy(DataLocal.szClassName, "SAS Window class"); strcpy(DataLocal.szWindowName, "SAS window"); DataLocal.fnFindWindow = (FINDWINDOW) GetProcAddress(hUser32, "FindWindowA"); if (DataLocal.fnFindWindow == NULL) __leave; // Allocate memory in the remote process and write a copy of initialized INJDATA into it size = sizeof(INJDATA); pDataRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!pDataRemote) __leave; if (!WriteProcessMemory(hProcess, pDataRemote, &DataLocal, size, &dwNumBytesCopied) || dwNumBytesCopied != size) __leave; // Allocate memory in remote process and write a copy of GetSASWnd() into it size = (PBYTE)AfterGetSASWnd - (PBYTE)GetSASWnd; pGetSASWndRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!pGetSASWndRemote) __leave; if (!WriteProcessMemory(hProcess, pGetSASWndRemote, &GetSASWnd, size, &dwNumBytesCopied) || dwNumBytesCopied != size) __leave; // Start execution of remote GetSASWnd() hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pGetSASWndRemote, pDataRemote, 0 , &dwThreadId); // Failed if (!hThread) __leave; // Wait for GetSASWnd() to terminate and get return code (SAS Wnd handle) WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, (PDWORD) &hSASWnd); // Didn't found "SAS window" if (!hSASWnd) __leave; // Cleanup VirtualFreeEx(hProcess, pGetSASWndRemote, 0, MEM_RELEASE); VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE); pGetSASWndRemote = NULL; pDataRemote = NULL; // Allocate memory in remote process and write a copy of SASWindowProc() into it size = (PBYTE)AfterSASWindowProc - (PBYTE)SASWindowProc; pSASWinProcRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!pSASWinProcRemote) __leave; if (!WriteProcessMemory(hProcess, pSASWinProcRemote, &SASWindowProc, size, &dwNumBytesCopied) || dwNumBytesCopied != size) __leave; // Is remote process unicode ? fUnicode = IsWindowUnicode(hSASWnd); // Initialize the INJDATA structure DataLocal.fnSetWindowLong = (SETWINDOWLONG) GetProcAddress(hUser32, fUnicode ? "SetWindowLongW" : "SetWindowLongA"); DataLocal.fnCallWindowProc = (CALLWINDOWPROC) GetProcAddress(hUser32, fUnicode ? "CallWindowProcW": "CallWindowProcA"); DataLocal.fnSASWndProc = (WNDPROC) pSASWinProcRemote; DataLocal.hwnd = hSASWnd; if (DataLocal.fnSetWindowLong == NULL || DataLocal.fnCallWindowProc == NULL) { __leave; } // Allocate memory in the remote process and write a copy of initialized INJDATA into it size = sizeof(INJDATA); pDataRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!pDataRemote) __leave; if (!WriteProcessMemory(hProcess, pDataRemote, &DataLocal, size, &dwNumBytesCopied) || dwNumBytesCopied != size) __leave; // Change dummy INJDATA address in SASWindowProc() by the real INJDATA pointer p = (PBYTE)&SASWindowProc; size = (PBYTE)AfterSASWindowProc - (PBYTE)SASWindowProc; SearchSize = size - sizeof(DWORD) + 1; FoundDummyAddr = FALSE; for (; SearchSize > 0; p++, SearchSize--) { if (*(DWORD *)p == DUMMY_ADDR) // Found { nDummyOffset = p - (PBYTE)&SASWindowProc; if (!WriteProcessMemory(hProcess, pSASWinProcRemote + nDummyOffset, &pDataRemote, sizeof(pDataRemote), &dwNumBytesCopied) || dwNumBytesCopied != sizeof(pDataRemote)) { __leave; } FoundDummyAddr = TRUE; break; } } // Couldn't change the dummy INJDATA addr. by the real addr. in SASWindowProc() !?! // Don't execute the remote copy of SASWindowProc() because the pData pointer is invalid ! if (!FoundDummyAddr) { __leave; } // Allocate memory in the remote process and write a copy of InjectFunc() to the allocated memory size = (PBYTE)AfterInjectFunc - (PBYTE)InjectFunc; pCodeRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!pCodeRemote) __leave; if (!WriteProcessMemory(hProcess, pCodeRemote, &InjectFunc, size, &dwNumBytesCopied) || dwNumBytesCopied != size) __leave; // Start execution of remote InjectFunc() hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pCodeRemote, pDataRemote, 0 , &dwThreadId); if (!hThread) __leave; // Wait for InjectFunc() to terminate and get return code WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, (PDWORD) &nSuccess); // InjectFunc() successfull // if (nSuccess) // MessageBeep(0); } __finally { // Failed ? if (!nSuccess) { // Release memory for INJDATA and SASWindowProc() if (pDataRemote) VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE); if (pSASWinProcRemote) VirtualFreeEx(hProcess, pSASWinProcRemote, 0, MEM_RELEASE); pDataRemote = NULL; pSASWinProcRemote = NULL; } // Release remote GetSASWnd() if (pGetSASWndRemote) VirtualFreeEx(hProcess, pGetSASWndRemote, 0, MEM_RELEASE); // Release remote InjectFunc() (no longer needed) if (pCodeRemote) VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE); if (hThread) CloseHandle(hThread); } CloseHandle(hProcess); // Disable the DEBUG privilege EnablePrivilege(SE_DEBUG_NAME, FALSE); return nSuccess; // 0=failure; 1=success }
/* * Class: sun_tools_attach_WindowsVirtualMachine * Method: enqueue * Signature: (JZLjava/lang/String;[Ljava/lang/Object;)V */ JNIEXPORT void JNICALL Java_sun_tools_attach_WindowsVirtualMachine_enqueue (JNIEnv *env, jclass cls, jlong handle, jbyteArray stub, jstring cmd, jstring pipename, jobjectArray args) { DataBlock data; DataBlock* pData; DWORD* pCode; DWORD numBytes; DWORD stubLen; HANDLE hProcess, hThread; jint argsLen, i; jbyte* stubCode; jboolean isCopy; /* * Setup data to copy to target process */ data._LoadLibrary = _LoadLibrary; data._GetProcAddress = _GetProcAddress; strcpy(data.jvmLib, "jvm"); strcpy(data.func1, "JVM_EnqueueOperation"); strcpy(data.func2, "_JVM_EnqueueOperation@20"); /* * Command and arguments */ jstring_to_cstring(env, cmd, data.cmd, MAX_CMD_LENGTH); argsLen = (*env)->GetArrayLength(env, args); if (argsLen > 0) { if (argsLen > MAX_ARGS) { JNU_ThrowInternalError(env, "Too many arguments"); } for (i=0; i<argsLen; i++) { jobject obj = (*env)->GetObjectArrayElement(env, args, i); if (obj == NULL) { data.arg[i][0] = '\0'; } else { jstring_to_cstring(env, obj, data.arg[i], MAX_ARG_LENGTH); } if ((*env)->ExceptionOccurred(env)) return; } } for (i=argsLen; i<MAX_ARGS; i++) { data.arg[i][0] = '\0'; } /* pipe name */ jstring_to_cstring(env, pipename, data.pipename, MAX_PIPE_NAME_LENGTH); /* * Allocate memory in target process for data and code stub * (assumed aligned and matches architecture of target process) */ hProcess = (HANDLE)handle; pData = (DataBlock*) VirtualAllocEx( hProcess, 0, sizeof(DataBlock), MEM_COMMIT, PAGE_READWRITE ); if (pData == NULL) { JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed"); return; } WriteProcessMemory( hProcess, (LPVOID)pData, (LPVOID)&data, (DWORD)sizeof(DataBlock), &numBytes ); stubLen = (DWORD)(*env)->GetArrayLength(env, stub); stubCode = (*env)->GetByteArrayElements(env, stub, &isCopy); pCode = (PDWORD) VirtualAllocEx( hProcess, 0, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if (pCode == NULL) { JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed"); VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE); return; } WriteProcessMemory( hProcess, (LPVOID)pCode, (LPVOID)stubCode, (DWORD)stubLen, &numBytes ); if (isCopy) { (*env)->ReleaseByteArrayElements(env, stub, stubCode, JNI_ABORT); } /* * Create thread in target process to execute code */ hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pCode, pData, 0, NULL ); if (hThread != NULL) { if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0) { JNU_ThrowIOExceptionWithLastError(env, "WaitForSingleObject failed"); } else { DWORD exitCode; GetExitCodeThread(hThread, &exitCode); if (exitCode) { switch (exitCode) { case ERR_OPEN_JVM_FAIL : JNU_ThrowIOException(env, "jvm.dll not loaded by target process"); break; case ERR_GET_ENQUEUE_FUNC_FAIL : JNU_ThrowIOException(env, "Unable to enqueue operation: the target VM does not support attach mechanism"); break; default : JNU_ThrowInternalError(env, "Remote thread failed for unknown reason"); } } } CloseHandle(hThread); } else { JNU_ThrowIOExceptionWithLastError(env, "CreateRemoteThread failed"); } VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE); VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE); }
int do_everything(int argc, LPCWSTR argv[]) { HRESULT hr = S_OK; // parse command line CPrefs prefs(argc, argv, hr); if (FAILED(hr)) { ERR(L"CPrefs::CPrefs constructor failed: hr = 0x%08x", hr); return -__LINE__; } if (S_FALSE == hr) { // nothing to do return 0; } // create a "loopback capture has started" event HANDLE hStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == hStartedEvent) { ERR(L"CreateEvent failed: last error is %u", GetLastError()); return -__LINE__; } CloseHandleOnExit closeStartedEvent(hStartedEvent); // create a "stop capturing now" event HANDLE hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == hStopEvent) { ERR(L"CreateEvent failed: last error is %u", GetLastError()); return -__LINE__; } CloseHandleOnExit closeStopEvent(hStopEvent); // create arguments for loopback capture thread LoopbackCaptureThreadFunctionArguments threadArgs; threadArgs.hr = E_UNEXPECTED; // thread will overwrite this threadArgs.pMMDevice = prefs.m_pMMDevice; threadArgs.bInt16 = prefs.m_bInt16; threadArgs.hFile = prefs.m_hFile; threadArgs.hStartedEvent = hStartedEvent; threadArgs.hStopEvent = hStopEvent; threadArgs.nFrames = 0; HANDLE hThread = CreateThread( NULL, 0, LoopbackCaptureThreadFunction, &threadArgs, 0, NULL ); if (NULL == hThread) { ERR(L"CreateThread failed: last error is %u", GetLastError()); return -__LINE__; } CloseHandleOnExit closeThread(hThread); // wait for either capture to start or the thread to end HANDLE waitArray[2] = { hStartedEvent, hThread }; DWORD dwWaitResult; dwWaitResult = WaitForMultipleObjects( _countof(waitArray), waitArray, FALSE, INFINITE ); if (WAIT_OBJECT_0 + 1 == dwWaitResult) { ERR(L"Thread aborted before starting to loopback capture: hr = 0x%08x", threadArgs.hr); return -__LINE__; } if (WAIT_OBJECT_0 != dwWaitResult) { ERR(L"Unexpected WaitForMultipleObjects return value %u", dwWaitResult); return -__LINE__; } // at this point capture is running // wait for the user to press a key or for capture to error out { WaitForSingleObjectOnExit waitForThread(hThread); SetEventOnExit setStopEvent(hStopEvent); HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (INVALID_HANDLE_VALUE == hStdIn) { ERR(L"GetStdHandle returned INVALID_HANDLE_VALUE: last error is %u", GetLastError()); return -__LINE__; } LOG(L"%s", L"Press Enter to quit..."); HANDLE rhHandles[2] = { hThread, hStdIn }; bool bKeepWaiting = true; while (bKeepWaiting) { dwWaitResult = WaitForMultipleObjects(2, rhHandles, FALSE, INFINITE); switch (dwWaitResult) { case WAIT_OBJECT_0: // hThread ERR(L"%s", L"The thread terminated early - something bad happened"); bKeepWaiting = false; break; case WAIT_OBJECT_0 + 1: // hStdIn // see if any of them was an Enter key-up event INPUT_RECORD rInput[128]; DWORD nEvents; if (!ReadConsoleInput(hStdIn, rInput, _countof(rInput), &nEvents)) { ERR(L"ReadConsoleInput failed: last error is %u", GetLastError()); bKeepWaiting = false; } else { for (DWORD i = 0; i < nEvents; i++) { if ( KEY_EVENT == rInput[i].EventType && VK_RETURN == rInput[i].Event.KeyEvent.wVirtualKeyCode && !rInput[i].Event.KeyEvent.bKeyDown ) { LOG(L"%s", L"Stopping capture..."); bKeepWaiting = false; break; } } // if none of them were Enter key-up events, // continue waiting } break; default: ERR(L"WaitForMultipleObjects returned unexpected value 0x%08x", dwWaitResult); bKeepWaiting = false; break; } // switch } // while } // naked scope // at this point the thread is definitely finished DWORD exitCode; if (!GetExitCodeThread(hThread, &exitCode)) { ERR(L"GetExitCodeThread failed: last error is %u", GetLastError()); return -__LINE__; } if (0 != exitCode) { ERR(L"Loopback capture thread exit code is %u; expected 0", exitCode); return -__LINE__; } if (S_OK != threadArgs.hr) { ERR(L"Thread HRESULT is 0x%08x", threadArgs.hr); return -__LINE__; } // everything went well... fixup the fact chunk in the file MMRESULT result = mmioClose(prefs.m_hFile, 0); prefs.m_hFile = NULL; if (MMSYSERR_NOERROR != result) { ERR(L"mmioClose failed: MMSYSERR = %u", result); return -__LINE__; } // reopen the file in read/write mode MMIOINFO mi = {0}; prefs.m_hFile = mmioOpen(const_cast<LPWSTR>(prefs.m_szFilename), &mi, MMIO_READWRITE); if (NULL == prefs.m_hFile) { ERR(L"mmioOpen(\"%ls\", ...) failed. wErrorRet == %u", prefs.m_szFilename, mi.wErrorRet); return -__LINE__; } // descend into the RIFF/WAVE chunk MMCKINFO ckRIFF = {0}; ckRIFF.ckid = MAKEFOURCC('W', 'A', 'V', 'E'); // this is right for mmioDescend result = mmioDescend(prefs.m_hFile, &ckRIFF, NULL, MMIO_FINDRIFF); if (MMSYSERR_NOERROR != result) { ERR(L"mmioDescend(\"WAVE\") failed: MMSYSERR = %u", result); return -__LINE__; } // descend into the fact chunk MMCKINFO ckFact = {0}; ckFact.ckid = MAKEFOURCC('f', 'a', 'c', 't'); result = mmioDescend(prefs.m_hFile, &ckFact, &ckRIFF, MMIO_FINDCHUNK); if (MMSYSERR_NOERROR != result) { ERR(L"mmioDescend(\"fact\") failed: MMSYSERR = %u", result); return -__LINE__; } // write the correct data to the fact chunk LONG lBytesWritten = mmioWrite( prefs.m_hFile, reinterpret_cast<PCHAR>(&threadArgs.nFrames), sizeof(threadArgs.nFrames) ); if (lBytesWritten != sizeof(threadArgs.nFrames)) { ERR(L"Updating the fact chunk wrote %u bytes; expected %u", lBytesWritten, (UINT32)sizeof(threadArgs.nFrames)); return -__LINE__; } // ascend out of the fact chunk result = mmioAscend(prefs.m_hFile, &ckFact, 0); if (MMSYSERR_NOERROR != result) { ERR(L"mmioAscend(\"fact\") failed: MMSYSERR = %u", result); return -__LINE__; } // let prefs' destructor call mmioClose return 0; }
int main() { // In this program we create 2 threads which each access the // same Point object. Hence we will need to provide synchronization. // Because in one case we set isMover = TRUE and in the other case // we set isMover = FALSE, one of the threads continually changes // the Point's x and y values while the other thread displays these // values. Note that both threads have the same thread entry function // even though they act completely differently. // With the synchronization statements removed, you will have to // look closely at the program output to spot those locations where // x and y differ. They will differ by only 1, with x being the // larger number. Point * p = new Point(); ThreadY * o1 = new ThreadY(true, p); HANDLE hth1; unsigned uiThread1ID; hth1 = (HANDLE)_beginthreadex(NULL, // security 0, // stack size ThreadY::ThreadStaticStartUp, o1, // arg list CREATE_SUSPENDED, // so we can later call ResumeThread() &uiThread1ID); if (hth1 == 0) printf("Failed to create thread 1\n"); DWORD dwExitCode; GetExitCodeThread(hth1, &dwExitCode); // should be STILL_ACTIVE = 0x00000103 = 259 printf("initial thread 1 exit code = %u\n", dwExitCode); ThreadY * o2 = new ThreadY(false, p); HANDLE hth2; unsigned uiThread2ID; hth2 = (HANDLE)_beginthreadex(NULL, // security 0, // stack size ThreadY::ThreadStaticStartUp, o2, // arg list CREATE_SUSPENDED, // so we can later call ResumeThread() &uiThread2ID); if (hth2 == 0) printf("Failed to create thread 2\n"); GetExitCodeThread(hth2, &dwExitCode); // should be STILL_ACTIVE = 0x00000103 = 259 printf("initial thread 2 exit code = %u\n", dwExitCode); // If we hadn't specified CREATE_SUSPENDED in the call to _beginthreadex() // we wouldn't now need to call ResumeThread(). ResumeThread(hth1); // Jaeschke's // t1->Start(); ResumeThread(hth2); // We now want the primary thread to sleep to allow time for // the other threads to come alive. This ensures the primary // thread will have to compete for access to the Point object. Sleep(100); // In C++/CLI the process continues until the last thread exits. // That is, the thread's have independent lifetimes. Hence // Jaeschke's original code was designed to show that the primary // thread could exit and not influence the other threads. // However in C++ the process terminates when the primary thread exits // and when the process terminates all its threads are then terminated. // Hence if you comment out the following waits, the non-primary // threads will never get a chance to run. WaitForSingleObject(hth1, INFINITE); WaitForSingleObject(hth2, INFINITE); GetExitCodeThread(hth1, &dwExitCode); printf("thread 1 exited with code %u\n", dwExitCode); GetExitCodeThread(hth2, &dwExitCode); printf("thread 2 exited with code %u\n", dwExitCode); // The handle returned by _beginthreadex() has to be closed // by the caller of _beginthreadex(). CloseHandle(hth1); CloseHandle(hth2); delete o1; o1 = NULL; delete o2; o2 = NULL; printf("Primary thread terminating.\n"); }
int MyAssertProc(const wchar_t* pszFile, int nLine, const wchar_t* pszTest, bool abNoPipe) { #ifdef _DEBUG static bool lbSkip = false; if (lbSkip) return 1; #endif HANDLE hHeap = GetProcessHeap(); MyAssertInfo* pa = (MyAssertInfo*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(MyAssertInfo)); if (!pa) return -1; wchar_t *szExeName = (wchar_t*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (MAX_PATH+1)*sizeof(wchar_t)); if (szExeName && !GetModuleFileNameW(NULL, szExeName, MAX_PATH+1)) szExeName[0] = 0; pa->bNoPipe = abNoPipe; msprintf(pa->szTitle, countof(pa->szTitle), L"CEAssert PID=%u TID=%u", GetCurrentProcessId(), GetCurrentThreadId()); msprintf(pa->szDebugInfo, countof(pa->szDebugInfo), L"Assertion in %s\n%s\n\n%s: %i\n\nPress 'Retry' to trap.", szExeName ? szExeName : L"", pszTest ? pszTest : L"", pszFile, nLine); DWORD dwCode = 0; if (gAllowAssertThread == am_Thread) { DWORD dwTID; HANDLE hThread = CreateThread(NULL, 0, MyAssertThread, pa, 0, &dwTID); if (hThread == NULL) { dwCode = IDRETRY; goto wrap; } WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &dwCode); CloseHandle(hThread); goto wrap; } #ifdef ASSERT_PIPE_ALLOWED #ifdef _DEBUG if (!abNoPipe && (gAllowAssertThread == am_Pipe)) { HWND hConWnd = GetConEmuHWND(2); HWND hGuiWnd = ghConEmuWnd; // -- искать - нельзя. Если мы НЕ в ConEmu - нельзя стучаться в другие копии!!! //#ifndef CONEMU_MINIMAL //if (hGuiWnd == NULL) //{ // hGuiWnd = FindWindowEx(NULL, NULL, VirtualConsoleClassMain, NULL); //} //#endif if (hGuiWnd && !gbInMyAssertTrap) { gbInMyAssertTrap = true; gbInMyAssertPipe = true; gnInMyAssertThread = GetCurrentThreadId(); ResetEvent(ghInMyAssertTrap); dwCode = GuiMessageBox(abNoPipe ? NULL : hGuiWnd, pa->szDebugInfo, pa->szTitle, MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_RETRYCANCEL); gbInMyAssertTrap = false; gbInMyAssertPipe = false; SetEvent(ghInMyAssertTrap); gnInMyAssertThread = 0; goto wrap; } } while (gbInMyAssertPipe && (gnInMyAssertThread != GetCurrentThreadId())) { Sleep(250); } #endif #endif // В консольных приложениях попытка запустить CreateThread(MyAssertThread) может зависать dwCode = MyAssertThread(pa); wrap: if (pa) HeapFree(hHeap, 0, pa); if (szExeName) HeapFree(hHeap, 0, szExeName); return (dwCode == IDRETRY) ? -1 : 1; }
void WINAPI InjectSelf(DWORD pid, PTHREAD_START_ROUTINE callback, LPVOID payload, int payloadSize, LPDWORD lpExitCode) { HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid); HMODULE hMod; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)callback, &hMod); struct _mLocal { unsigned char code[256]; wchar_t fileName[MAX_PATH]; char payloadData[1]; } mLocal; int allocSize = sizeof(mLocal) - sizeof(mLocal.payloadData) + payloadSize; DWORD pRemote = (DWORD)VirtualAllocEx(hProcess, NULL, allocSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); unsigned char* ptr = mLocal.code; //55 PUSH EBP //8BEC MOV EBP,ESP //83EC 08 SUB ESP,8 PTR_APPEND_STR("\x55\x8B\xEC\x83\xEC\x08"); //68 ???????? PUSH ? ; FileName PTR_APPEND_5BY(0x68, pRemote + offsetof(_mLocal, fileName)); //E8 ???????? CALL ? ; LoadLibraryW HMODULE kernel32 = GetModuleHandleW(L"kernel32"); DWORD offs = (DWORD)pRemote + (ptr - mLocal.code) + 5; PTR_APPEND_5BY(0xE8, (DWORD)GetProcAddress(kernel32, "LoadLibraryW") - offs); //8945 FC MOV DWORD PTR SS:[EBP-4],EAX PTR_APPEND_STR("\x89\x45\xFC"); //68 ???????? PUSH ? ; payload PTR_APPEND_5BY(0x68, pRemote + offsetof(_mLocal, payloadData)); //8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] PTR_APPEND_STR("\x8B\x45\xFC"); //05 ???????? ADD EAX,?; callback offset PTR_APPEND_5BY(0x05, (DWORD)callback - (DWORD)hMod); //FFD0 CALL EAX //8945 F8 MOV DWORD PTR SS:[EBP-8],EAX //8B4D FC MOV ECX,DWORD PTR SS:[EBP-4] //51 PUSH ECX ; hLibModule PTR_APPEND_STR("\xFF\xD0\x89\x45\xF8\x8B\x4D\xFC\x51"); //E8 ???????? CALL ? ; FreeLibrary offs = (DWORD)pRemote + (ptr - mLocal.code) + 5; PTR_APPEND_5BY(0xE8, (DWORD)GetProcAddress(kernel32, "FreeLibrary") - offs); //8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] //8BE5 MOV ESP,EBP //5D POP EBP //C2 0400 RETN 4 PTR_APPEND_STR("\x8B\x45\xF8\x8B\xE5\x5D\xC2\x04\x00"); GetModuleFileNameW(hMod, mLocal.fileName, MAX_PATH); WriteProcessMemory(hProcess, (void*)pRemote, &mLocal, sizeof(mLocal), NULL); WriteProcessMemory(hProcess, (void*)(pRemote + offsetof(_mLocal, payloadData)), payload, payloadSize, NULL); HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (PTHREAD_START_ROUTINE)pRemote, 0, 0, NULL); WaitForSingleObject(hThread, INFINITE); if (lpExitCode) GetExitCodeThread(hThread, lpExitCode); CloseHandle(hThread); VirtualFreeEx(hProcess, (void*)pRemote, allocSize, MEM_RELEASE); CloseHandle(hProcess); }
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int index; int status; HANDLE thread; wfContext* wfc; DWORD dwExitCode; rdpContext* context; rdpSettings* settings; RDP_CLIENT_ENTRY_POINTS clientEntryPoints; int ret = 0; ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS)); clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS); clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION; RdpClientEntry(&clientEntryPoints); context = freerdp_client_context_new(&clientEntryPoints); settings = context->settings; wfc = (wfContext*) context; settings->SoftwareGdi = TRUE; context->argc = __argc; context->argv = (char**) malloc(sizeof(char*) * __argc); if (!context->argv) { ret = 1; goto out; } for (index = 0; index < context->argc; index++) { context->argv[index] = _strdup(__argv[index]); if (!context->argv[index]) { ret = 1; for (--index; index >= 0; --index) free(context->argv[index]); free(context->argv); context->argv = NULL; goto out; } } status = freerdp_client_settings_parse_command_line(settings, context->argc, context->argv, FALSE); status = freerdp_client_settings_command_line_status_print(settings, status, context->argc, context->argv); if (status) { freerdp_client_context_free(context); return 0; } freerdp_client_start(context); thread = freerdp_client_get_thread(context); WaitForSingleObject(thread, INFINITE); GetExitCodeThread(thread, &dwExitCode); freerdp_client_stop(context); out: freerdp_client_context_free(context); return ret; }
int _tmain(int argc, TCHAR* argv[]) { // POINT p; // DWORD px,py; // DWORD temp; //이상 마우스 관련 변수 HANDLE tHandle[2];//이상 쓰레드 관련변수 DWORD threadId[2]; DWORD counter=0, tmp=0; _tprintf(_T("%d\n"), GetSystemMetrics(SM_CYVIRTUALSCREEN)); _tprintf(_T("%d\n"),GetSystemMetrics(SM_CYSCREEN)); // GetSystemMetrics(SM_CXSCREEN) 함수는 현재 주모니터의 너비를 리턴한다 // GetSystemMetrics(SM_CYSCREEN) 함수는 현재 주모니터의 높이를 리턴한다 // GetSystemMetrics(SM_CYVIRTUALSCREEN) 서브모니터의 높이를 리턴한다 // GetSystemMetrics(SM_CXVIRTUALSCREEN) 두너모니터의 너비의 합을 리턴한다 // GetSystemMetrics(SM_CMONITORS) 연결된 모니터 정보를 가져온다. 듀얼지원안되면0 모니터하나면1 다중이면2 //쓰레드 생성 tHandle[0] = CreateThread( NULL, 0, ThreadProc, NULL, 0, &threadId[0]); tHandle[1] = CreateThread( NULL, 0, ThreadProc1, NULL, 0, &threadId[1]); //쓰레드 검사 if(tHandle[0] == NULL || tHandle[1] == NULL){ _tprintf(_T("thread creation fault!") ); return -1; } //2개의 쓰레드가 signaled 상태 될때까지 기다림 WaitForMultipleObjects(2, tHandle, TRUE, INFINITE); //쓰레드의 반환을 받음 GetExitCodeThread(tHandle[0], &tmp); counter += tmp; GetExitCodeThread(tHandle[1], &tmp); counter += tmp; _tprintf(_T("total count : %d"), counter); /* while(1){ GetCursorPos(&p); //마우스 위치값얻어오기 //printf("%d, %d \n", p.x, p.y); //마우스위치출력 px=p.x; py=p.y; temp = MouseClickTest(); if(1==temp) _tprintf(_T("click!\n")); else if(2==temp) _tprintf(_T("right click!\n")); else if(3==temp) break; else if(4==temp) _tprintf(_T("wheel click!\n")); if(px==(GetSystemMetrics(SM_CXVIRTUALSCREEN)-1)) SetCursorPos(1,py); //마우스 위치를 이동시키기 if(px==0) SetCursorPos(GetSystemMetrics(SM_CXVIRTUALSCREEN)-2,py); //마우스 위치를 이동시키기 //마우스 위쪽 -> 아래쪽, 아래쪽 -> 위쪽 if(GetSystemMetrics(SM_CXVIRTUALSCREEN)-GetSystemMetrics(SM_CXSCREEN) > px){ if(py==(GetSystemMetrics(SM_CYSCREEN)-1)) SetCursorPos(px,1); //마우스 위치를 이동시키기 if(py==0) SetCursorPos(px,GetSystemMetrics(SM_CYSCREEN)-2); //마우스 위치를 이동시키기 }else{ if(py==(GetSystemMetrics(SM_CYVIRTUALSCREEN)-1)) SetCursorPos(px,1); //마우스 위치를 이동시키기 if(py==0) SetCursorPos(px,GetSystemMetrics(SM_CYVIRTUALSCREEN)-2); //마우스 위치를 이동시키기 } }*/ CloseHandle(tHandle[0]); CloseHandle(tHandle[1]); return 0; }
bool WinMIDIDevice::Update() { // If the PlayerThread is signalled, then it's dead. if (PlayerThread != nullptr && WaitForSingleObject(PlayerThread, 0) == WAIT_OBJECT_0) { static const char *const MMErrorCodes[] = { "No error", "Unspecified error", "Device ID out of range", "Driver failed enable", "Device already allocated", "Device handle is invalid", "No device driver present", "Memory allocation error", "Function isn't supported", "Error value out of range", "Invalid flag passed", "Invalid parameter passed", "Handle being used simultaneously on another thread", "Specified alias not found", "Bad registry database", "Registry key not found", "Registry read error", "Registry write error", "Registry delete error", "Registry value not found", "Driver does not call DriverCallback", "More data to be returned", }; static const char *const MidiErrorCodes[] = { "MIDI header not prepared", "MIDI still playing something", "MIDI no configured instruments", "MIDI hardware is still busy", "MIDI port no longer connected", "MIDI invalid MIF", "MIDI operation unsupported with open mode", "MIDI through device 'eating' a message", }; DWORD code = 0xABADCAFE; GetExitCodeThread(PlayerThread, &code); CloseHandle(PlayerThread); PlayerThread = nullptr; Printf("MIDI playback failure: "); if (code < countof(MMErrorCodes)) { Printf("%s\n", MMErrorCodes[code]); } else if (code >= MIDIERR_BASE && code < MIDIERR_BASE + countof(MidiErrorCodes)) { Printf("%s\n", MidiErrorCodes[code - MIDIERR_BASE]); } else { Printf("%08x\n", code); } return false; } return true; }
float sysapi_load_avg_raw(void) { static HANDLE threadHandle = NULL; static int threadID = -1; time_t currentTime; double totalLoad=0.0; DWORD exitCode = 0; BOOL createNewThread = FALSE; int numSamples=0, i; sysapi_internal_reconfig(); if (threadHandle == NULL) { ncpus = sysapi_ncpus(); InitializeCriticalSection(&cs); createNewThread = TRUE; } else { if ( ! GetExitCodeThread( threadHandle, &exitCode ) ) { dprintf(D_ALWAYS, "GetExitCodeThread() failed. (err=%li)\n", GetLastError()); } else { if ( exitCode != STILL_ACTIVE ) { // somehow the thread died, so we should get its // return code, dprintf it and then start a new thread. dprintf(D_ALWAYS, "loadavg thread died, restarting. " "(exit code=%li)\n", exitCode); CloseHandle(threadHandle); createNewThread = TRUE; } else { // thread is still alive and well. Go in peace. createNewThread = FALSE; } } } if ( createNewThread == TRUE ) { threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sample_load, NULL, 0, (LPDWORD)&threadID); if (threadHandle == NULL) { #ifndef TESTING dprintf(D_ALWAYS, "failed to create loadavg thread, errno = %d\n", GetLastError()); #endif return 0.0; } Sleep(SAMPLE_INTERVAL*5); /* wait for ~5 samples */ } currentTime = time(NULL); EnterCriticalSection(&cs); for (i=0; i < NUM_SAMPLES; i++) { /* if this sample occurred within the minute, then add to total */ if ((currentTime-60) <= samples[i].sampletime) { totalLoad += samples[i].load; numSamples++; } } LeaveCriticalSection(&cs); if (numSamples == 0) { #ifndef TESTING dprintf(D_ALWAYS, "no loadavg samples this minute, maybe thread died???\n"); #endif return 0.0; } #ifndef TESTING dprintf(D_LOAD, "loadavg=%.2f with %d samples\n", ((float)totalLoad)/((float)numSamples), numSamples); #endif return ((float)totalLoad)/((float)numSamples); }
DWORD DosStartProcess32(IN LPCSTR ExecutablePath, IN LPCSTR CommandLine, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL, IN BOOLEAN StartComSpec) { DWORD Result = ERROR_SUCCESS; HANDLE CommandThread; DOS_START_PROC32 DosStartProc32; #ifndef STANDALONE BOOL Success; VDM_COMMAND_INFO CommandInfo; #endif DosStartProc32.ExecutablePath = (LPSTR)ExecutablePath; DosStartProc32.CommandLine = (LPSTR)CommandLine; DosStartProc32.Environment = (LPSTR)Environment; #ifndef STANDALONE DosStartProc32.ComSpecInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*DosStartProc32.ComSpecInfo)); ASSERT(DosStartProc32.ComSpecInfo); DosStartProc32.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ASSERT(DosStartProc32.hEvent); #endif /* Pause the VM and detach from the console */ EmulatorPause(); DosProcessConsoleDetach(); /* Start the 32-bit process via another thread */ CommandThread = CreateThread(NULL, 0, &CommandThreadProc, &DosStartProc32, 0, NULL); if (CommandThread == NULL) { DisplayMessage(L"FATAL: Failed to create the command processing thread: %d", GetLastError()); Result = GetLastError(); goto Quit; } #ifndef STANDALONE /* Close the thread handle */ CloseHandle(CommandThread); /* Wait for the process to be ready to start */ WaitForSingleObject(DosStartProc32.hEvent, INFINITE); /* Wait for any potential new DOS app started by the 32-bit process */ RtlZeroMemory(&CommandInfo, sizeof(CommandInfo)); Retry: CommandInfo.VDMState = VDM_FLAG_NESTED_TASK | VDM_FLAG_DONT_WAIT; DPRINT1("Calling GetNextVDMCommand 32bit for possible new VDM task...\n"); Success = GetNextVDMCommand(&CommandInfo); DPRINT1("GetNextVDMCommand 32bit awaited, success = %s, last error = %d\n", Success ? "true" : "false", GetLastError()); /* * Check whether we were awaited because the 32-bit process was stopped, * or because it started a new DOS application. */ if (CommandInfo.CmdLen != 0 || CommandInfo.AppLen != 0 || CommandInfo.PifLen != 0) { DPRINT1("GetNextVDMCommand 32bit, this is for a new VDM task - CmdLen = %d, AppLen = %d, PifLen = %d\n", CommandInfo.CmdLen, CommandInfo.AppLen, CommandInfo.PifLen); /* Repeat the request */ Repeat = TRUE; /* * Set 'Reentry' to TRUE or FALSE depending on whether we are going * to reenter with a new COMMAND.COM. See the comment for: * BOP_CMD 0x10 'Get start information' * (dem.c!DosCmdInterpreterBop) for more details. */ Reentry = StartComSpec; /* If needed, start a new command interpreter to handle the possible incoming DOS commands */ if (StartComSpec) { // // DosStartProcess32 was only called by DosCreateProcess, called from INT 21h, // so the caller stack is already prepared for running a new DOS program // (Flags, CS and IP, and the extra interrupt number, are already pushed). // Result = DosStartComSpec(FALSE, Environment, ReturnAddress, &DosStartProc32.ComSpecInfo->ComSpecPsp); if (Result != ERROR_SUCCESS) { DosDisplayMessage("Failed to start a new Command Interpreter (Error: %u).\n", Result); goto Quit; } } else { /* Retrieve the PSP of the COMSPEC (current PSP set by DosLoadExecutable) */ DosStartProc32.ComSpecInfo->ComSpecPsp = Sda->CurrentPsp; Result = ERROR_SUCCESS; } /* Insert the new entry in the list; it will be freed when needed by COMMAND.COM */ InsertComSpecInfo(DosStartProc32.ComSpecInfo); } else { DPRINT1("GetNextVDMCommand 32bit, 32-bit app stopped\n"); /* Check whether this was our 32-bit app which was killed */ if (!DosStartProc32.ComSpecInfo->Terminated) { DPRINT1("Not our 32-bit app, retrying...\n"); goto Retry; } Result = DosStartProc32.ComSpecInfo->dwExitCode; /* Delete the entry */ RtlFreeHeap(RtlGetProcessHeap(), 0, DosStartProc32.ComSpecInfo); } #else /* Wait for the thread to finish */ WaitForSingleObject(CommandThread, INFINITE); GetExitCodeThread(CommandThread, &Result); /* Close the thread handle */ CloseHandle(CommandThread); DPRINT1("32-bit app stopped\n"); #endif Quit: #ifndef STANDALONE CloseHandle(DosStartProc32.hEvent); #endif /* Attach to the console and resume the VM */ DosProcessConsoleAttach(); EmulatorResume(); return Result; }
UIOHOOK_API int hook_enable() { int status = UIOHOOK_FAILURE; // Make sure the native thread is not already running. if (hook_is_enabled() != true) { // Create event handles for the thread hook. hook_control_handle = CreateEvent(NULL, TRUE, FALSE, "hook_control_handle"); LPTHREAD_START_ROUTINE lpStartAddress = &hook_thread_proc; hook_thread_handle = CreateThread(NULL, 0, lpStartAddress, NULL, 0, &hook_thread_id); if (hook_thread_handle != INVALID_HANDLE_VALUE) { logger(LOG_LEVEL_DEBUG, "%s [%u]: Start successful\n", __FUNCTION__, __LINE__); // Attempt to set the thread priority to time critical. // TODO This maybe a little overkill, re-evaluate. BOOL status_priority = SetThreadPriority(hook_thread_handle, THREAD_PRIORITY_TIME_CRITICAL); if (!status_priority) { logger(LOG_LEVEL_WARN, "%s [%u]: Could not set thread priority %li for thread %#p! (%#lX)\n", __FUNCTION__, __LINE__, (long) THREAD_PRIORITY_TIME_CRITICAL, hook_thread_handle, (unsigned long) GetLastError()); } // Wait for any possible thread exceptions to get thrown into // the queue WaitForSingleObject(hook_control_handle, INFINITE); // TODO Set the return status to the thread exit code. if (hook_is_enabled()) { logger(LOG_LEVEL_DEBUG, "%s [%u]: Start successful\n", __FUNCTION__, __LINE__); status = UIOHOOK_SUCCESS; } else { logger(LOG_LEVEL_ERROR, "%s [%u]: Initialization failure!\n", __FUNCTION__, __LINE__); // Wait for the thread to die. WaitForSingleObject(hook_thread_handle, INFINITE); DWORD thread_status; GetExitCodeThread(hook_thread_handle, &thread_status); status = (int) thread_status; logger(LOG_LEVEL_ERROR, "%s [%u]: Thread Result: %i!\n", __FUNCTION__, __LINE__, status); } } else { logger(LOG_LEVEL_ERROR, "%s [%u]: Thread create failure!\n", __FUNCTION__, __LINE__); status = UIOHOOK_ERROR_THREAD_CREATE; } } return status; }
/***************************************** * Load a library into a remote process. * *****************************************/ int InjectDll() { HANDLE hThread; // Thread handle HANDLE hProcess; // Process handle DWORD dwPID; // Process ID char szLibPath[MAX_PATH]; // Full DLL path void *pLibRemote; // Address (in the remote process) where szLibPath will be copied to // Enable DEBUG privilege if (!EnablePrivilege(SE_DEBUG_NAME, TRUE)) return 0; // Get remote process id dwPID = GetPIDFromName(szProcessName); if (dwPID == -1) return 0; // Open remote process hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); if (hProcess == NULL) return 0; // Get full path of the DLL if (!GetModuleFileName(hInst, szLibPath, MAX_PATH)) return 0; strcpy(strrchr(szLibPath, '\\') + 1 , szDllName); // Allocate memory in the remote process to store the szLibPath string pLibRemote = VirtualAllocEx(hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE); if (pLibRemote == NULL) return 0; // Copy the szLibPath string to the remote process. if (!WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath, sizeof(szLibPath), NULL)) return 0; // Load the DLL into the remote process // (via CreateRemoteThread() & LoadLibrary()) hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA"), pLibRemote, 0, NULL); // Failed if(hThread == NULL) { VirtualFreeEx(hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE); return 0; } // Wait for LoadLibrary() to finish and get return code (handle of loaded library) WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &hLibModule); CloseHandle(hThread); CloseHandle(hProcess); // Free remote memory for szLibPath VirtualFreeEx(hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE); // Remote LoadLibrary() failed if (!hLibModule) return 0; // Disable DEBUG privilege EnablePrivilege(SE_DEBUG_NAME, FALSE); return 1; }
BOOL WINAPI InjectLibrary(HANDLE hProcess, CTSTR lpDLL) { UPARAM procAddress; DWORD dwTemp,dwSize; LPVOID lpStr = NULL; BOOL bWorks,bRet=0; HANDLE hThread = NULL; SIZE_T writtenSize; if(!hProcess) return 0; dwSize = ssize((TCHAR*)lpDLL); //-------------------------------------------------------- int obfSize = 12; char pWPMStr[19], pCRTStr[19], pVAEStr[15], pVFEStr[14], pLLStr[13]; mcpy(pWPMStr, "RvnrdPqmni|}Dmfegm", 19); //WriteProcessMemory with each character obfuscated mcpy(pCRTStr, "FvbgueQg`c{k]`yotp", 19); //CreateRemoteThread with each character obfuscated mcpy(pVAEStr, "WiqvpekGeddiHt", 15); //VirtualAllocEx with each character obfuscated mcpy(pVFEStr, "Wiqvpek@{mnOu", 14); //VirtualFreeEx with each character obfuscated mcpy(pLLStr, "MobfImethzr", 12); //LoadLibrary with each character obfuscated #ifdef UNICODE pLLStr[11] = 'W'; #else pLLStr[11] = 'A'; #endif pLLStr[12] = 0; obfSize += 6; for (int i=0; i<obfSize; i++) pWPMStr[i] ^= i^5; for (int i=0; i<obfSize; i++) pCRTStr[i] ^= i^5; obfSize -= 4; for (int i=0; i<obfSize; i++) pVAEStr[i] ^= i^1; obfSize -= 1; for (int i=0; i<obfSize; i++) pVFEStr[i] ^= i^1; obfSize -= 2; for (int i=0; i<obfSize; i++) pLLStr[i] ^= i^1; HMODULE hK32 = GetModuleHandle(TEXT("KERNEL32")); WPMPROC pWriteProcessMemory = (WPMPROC)GetProcAddress(hK32, pWPMStr); CRTPROC pCreateRemoteThread = (CRTPROC)GetProcAddress(hK32, pCRTStr); VAEPROC pVirtualAllocEx = (VAEPROC)GetProcAddress(hK32, pVAEStr); VFEPROC pVirtualFreeEx = (VFEPROC)GetProcAddress(hK32, pVFEStr); //-------------------------------------------------------- lpStr = (LPVOID)(*pVirtualAllocEx)(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(!lpStr) goto end; bWorks = (*pWriteProcessMemory)(hProcess, lpStr, (LPVOID)lpDLL, dwSize, &writtenSize); if(!bWorks) goto end; procAddress = (UPARAM)GetProcAddress(hK32, pLLStr); if(!procAddress) goto end; hThread = (*pCreateRemoteThread)(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)procAddress, lpStr, 0, &dwTemp); if(!hThread) goto end; if(WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0) { DWORD dw; GetExitCodeThread(hThread, &dw); bRet = dw != 0; SetLastError(0); } end: DWORD lastError; if(!bRet) lastError = GetLastError(); if(hThread) CloseHandle(hThread); if(lpStr) (*pVirtualFreeEx)(hProcess, lpStr, 0, MEM_RELEASE); if(!bRet) SetLastError(lastError); return bRet; }
int EjectCode () { HANDLE hProcess; // Remote process handle DWORD *pCodeRemote; // Address of EjectFunc() in the remote process HANDLE hThread = NULL; // The handle and ID of the thread executing DWORD dwThreadId = 0; // the remote EjectFunc(). int nSuccess = 0; // EjectFunc() success ? DWORD dwNumBytesCopied = 0; // Number of bytes written to the remote process. DWORD size; // Calculated function size (= AfterFunc() - Func()) // Enable Debug privilege (needed for some processes) EnablePrivilege(SE_DEBUG_NAME, TRUE); // Remote INDATA and SASWindowProc() must exist if (!pDataRemote || !pSASWinProcRemote) return 0; // Open the process hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); if (hProcess == NULL) return 0; // Allocate memory in the remote process and write a copy of EjectFunc() to the allocated memory size = (PBYTE)AfterEjectFunc - (PBYTE)EjectFunc; pCodeRemote = (PDWORD) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!pCodeRemote) { CloseHandle(hProcess); return 0; } if (!WriteProcessMemory(hProcess, pCodeRemote, &EjectFunc, size, &dwNumBytesCopied) || dwNumBytesCopied != size) { VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return 0; } // Start execution of the remote EjectFunc() hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pCodeRemote, pDataRemote, 0 , &dwThreadId); // Failed if (!hThread) { goto END; } // Wait for EjectFunc() to terminate and get return code WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, (PDWORD) &nSuccess); // Failed to restore old window procedure ? // Then leave INJDATA and the SASWindowProc() if (nSuccess == 0) goto END; // Release memory for remote INJDATA and SASWindowProc() if (pDataRemote) VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE); if (pSASWinProcRemote) VirtualFreeEx(hProcess, pSASWinProcRemote, 0, MEM_RELEASE); pDataRemote = NULL; pSASWinProcRemote = NULL; // MessageBeep(0); // success END: if (hThread) CloseHandle(hThread); // Release EjectFunc() memory if (pCodeRemote) VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE); CloseHandle(hProcess); // Disable the DEBUG privilege EnablePrivilege(SE_DEBUG_NAME, FALSE); return nSuccess; // 0=failure; 1=success }
// // Invoke() // // invoke the GIB program and return the recommended play // int CGIB::Invoke(CPlayer* pPlayer, CHandHoldings* pHand, CHandHoldings* pDummyHand, CPlayerStatusDialog* pStatusDlg) { SECURITY_ATTRIBUTES saAttr; // // create the GIB monitor dialog // CGIBDialog gibDialog(pMAINFRAME); int nProcessingTime = theApp.GetValue(tnGIBAnalysisTime); gibDialog.m_nProcessTime = nProcessingTime; // gibDialog.m_hEventCancel = m_hEventCancel; // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // // create input and output pipes for the child process // // Create a pipe for the child process's STDOUT. if (!CreatePipe(&m_hChildStdoutRd, // returns the pipe's input handle &m_hChildStdoutWr, // returns the pipe's output handle &saAttr, 0)) { CString strError = "Stdout pipe creation failed\n"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); return ExitGracefully(-5); } // then create a pipe for the child process's STDIN. if (!CreatePipe(&m_hChildStdinRd, &m_hChildStdinWr, &saAttr, 0)) { CString strError = "Stdin pipe creation failed\n"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); return ExitGracefully(-5); } // // Now create the child process (GIB) // PROCESS_INFORMATION piProcInfo; if (!LaunchProgram(piProcInfo)) { TRACE("Create process failed"); return ExitGracefully(-1); } HANDLE hGIBProcess = piProcInfo.hProcess; DWORD nGIBProcessID = piProcInfo.dwProcessId; // now close the readable handle to the child's stdin SafeCloseHandle(m_hChildStdinRd); // and the writable handle to the child's stdout SafeCloseHandle(m_hChildStdoutWr); // //------------------------------------------------------------------ // // create the GIB input file // CFile file; CFileException fileException; CString strTempFile, strTempPath; GetTempPath(1024, strTempPath.GetBuffer(1024)); strTempPath.ReleaseBuffer(); GetTempFileName(strTempPath, "ezb", 0, strTempFile.GetBuffer(2048)); strTempFile.ReleaseBuffer(); // strTempFile.Format("%s\\%s", theApp.GetValueString(tszProgramDirectory), tszGIBTempFilename); /* LPTSTR szBuffer = strTempFile.GetBuffer(MAX_PATH); GetTempFileName(theApp.GetValueString(tszProgramDirectory), "ezb", 0, szBuffer); strTempFile.ReleaseBuffer(); */ // CString strInput; // strInput.Format("-T %d %s\n",theApp.GetValue(tnGIBAnalysisTime),strTempFile); int nCode = file.Open(strTempFile, CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite, &fileException); if (nCode == 0) { CString strError = "Error opening temporary input file for GIB"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); return ExitGracefully(-2); } // CString strFileContents; CreateGIBInputFile(file, pPlayer, pHand, pDummyHand, strFileContents); file.Close(); // then send the parameters line CString strParameters, strShortParameters; strParameters.Format("-T %d %s\n",nProcessingTime,strTempFile); strShortParameters.Format("-T %d",nProcessingTime); DWORD dwWritten; int nErrCode; if (!WriteFile(m_hChildStdinWr, (LPCTSTR)strParameters, strParameters.GetLength(), &dwWritten, NULL)) { CString strError = "Error providing parameters to GIB"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); nErrCode = GetLastError(); return ExitGracefully(-3); } // // update the GIB monitor window // CString strGIBText = "========================================\n"; strGIBText += FormString("Launching %s %s\n", theApp.GetValueString(tszGIBPath), strShortParameters); // strGIBText += FormString("Input file contents:\n%s", strFileContents); strGIBText += "Awaiting Responses...\n"; strGIBText += "----------------------------------------\n"; // pMAINFRAME->SetGIBMonitorText(strGIBText); pMAINFRAME->AppendGIBMonitorText(strGIBText); // //------------------------------------------------------------ // // now set up the wait loop and the cancel dialog, // then sit and wait for the process to run or for a cancel message // /* // // create the "Cancel GIB" dialog thread // (this is a user interface thread) // CGIBMonitorThread* pMonitorThread = new CGIBMonitorThread(m_hEventFinished, m_hEventCancel, nProcessingTime); pMonitorThread->CreateThread(CREATE_SUSPENDED); pMonitorThread->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL); pMonitorThread->ResumeThread(); // wait for the monitor thread to initialize DWORD nCode0 = WaitForSingleObject(m_hEventFinished, INFINITE); */ // // create the wait thread // (this is a worker thread) // GIBStruct gibData; gibData.hReadHandle = m_hChildStdoutRd; gibData.pGIBDialog = &gibDialog; CWinThread* pWaitThread = AfxBeginThread(CGIB::ReadGIBOutput, &gibData, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); // copy its handle se that we can check its exit code later HANDLE hWaitThread; BOOL bCode = ::DuplicateHandle(GetCurrentProcess(), pWaitThread->m_hThread, GetCurrentProcess(), &hWaitThread, 0, FALSE, DUPLICATE_SAME_ACCESS); // and launch the threads // MonitorThread->ResumeThread(); pWaitThread->ResumeThread(); // // Show the Wait/Cancel dialog // m_bGIBPending = TRUE; // mark dialog as active bCode = gibDialog.DoModal(); // see if the user cancelled if (!bCode) { /* // lock out the wait thread and cancel operations if (ClearGIBPending()) { */ // pMAINFRAME->SetStatusText("GIB cancelled."); // TerminateProcess(hGIBProcess, 0); TerminateThread(hWaitThread, 0); // wait for the read thread to end WaitForSingleObject(hWaitThread, INFINITE); // close the wait thread handle CloseHandle(hWaitThread); CloseHandle(hGIBProcess); // and delete the thread object delete pWaitThread; // close pipe handles SafeCloseHandle(m_hChildStdinWr); SafeCloseHandle(m_hChildStdoutRd); // and throw an exception throw CGIBException(); // } } /* // set up events HANDLE eventArray[2]; eventArray[0] = m_hEventCancel; eventArray[1] = pWaitThread->m_hThread; // // then sit back and wait for the thread(s) // for(;;) { // wait for the cancelled or finished messages DWORD nCode = WaitForMultipleObjects(2, // 2 events to wait for eventArray, // events array FALSE, // not all at once INFINITE); // wait 4-ever // if (nCode == WAIT_FAILED) { ASSERT(FALSE); break; } else if (nCode == WAIT_OBJECT_0) { // got the cancel message, so kill GIB & the wait thread // the following is very dangersous -- // so kids, don't try this at home TerminateThread(pWaitThread, 0); TerminateProcess(hGIBProcess, 0); return GIB_CANCEL; } else if (nCode == WAIT_OBJECT_0 + 1) { // GIB finished message // signal the GIB monitor that GIB has finished SetEvent(m_hEventFinished); break; } } */ // //------------------------------------------------------------ // // presumably, GIB has finished running // // wait for the GIB thread to exit, then get the card code DWORD nCardPlayed, nErrorCode; bCode = WaitForSingleObject(hWaitThread, INFINITE); bCode = GetExitCodeThread(hWaitThread, &nCardPlayed); if (!bCode) nErrorCode = GetLastError(); // close the wait thread handle CloseHandle(hWaitThread); // delete the temporary file DeleteFile(strTempFile); // and kill the child process // first send a Ctrl-C to the app // (this doesn't seem to do anything) CString strInput = "\03"; // Ctrl-C if (!WriteFile(m_hChildStdinWr, (LPCTSTR)strInput, strInput.GetLength(), &dwWritten, NULL)) { CString strError = "Error stopping GIB"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); nErrCode = GetLastError(); return ExitGracefully(-4); } // close the writable handle to the child's stdin SafeCloseHandle(m_hChildStdinWr); // then call terminateProcess TerminateProcess(hGIBProcess, 0); CloseHandle(hGIBProcess); // then close the readable handle to the child's stdout SafeCloseHandle(m_hChildStdoutRd); // // done // return nCardPlayed; }
/* * Elevate from local admin to local system via Named Pipe Impersonation. We spawn a cmd.exe under local * system which then connects to our named pipe and we impersonate this client. This can be done by an * Administrator without the need for SeDebugPrivilege. Works on 2000, XP, 2003 and 2008 for all local * administrators. On Vista and 7 it will only work if the host process has been elevated through UAC * first. Does not work on NT4. */ DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet) { DWORD dwResult = ERROR_SUCCESS; char * cpServiceName = NULL; THREAD * pThread = NULL; HANDLE hSem = NULL; char cServiceArgs[MAX_PATH] = {0}; char cServicePipe[MAX_PATH] = {0}; OSVERSIONINFO os = {0}; do { os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&os)) { BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe: GetVersionEx failed") } // filter out Windows NT4 if (os.dwMajorVersion == 4 && os.dwMinorVersion == 0) { SetLastError(ERROR_ACCESS_DENIED); BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe: Windows NT4 not supported.") } cpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_NAME); if (!cpServiceName) { BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. invalid arguments", ERROR_BAD_ARGUMENTS); } _snprintf_s(cServicePipe, sizeof(cServicePipe), MAX_PATH, "\\\\.\\pipe\\%s", cpServiceName); _snprintf_s(cServiceArgs, sizeof(cServiceArgs), MAX_PATH, "cmd.exe /c echo %s > %s", cpServiceName, cServicePipe); hSem = CreateSemaphore(NULL, 0, 1, NULL); pThread = thread_create(elevate_namedpipe_thread, &cServicePipe, remote, hSem); if (!pThread) { BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. thread_create failed", ERROR_INVALID_HANDLE); } if (!thread_run(pThread)) { BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. thread_run failed", ERROR_ACCESS_DENIED); } //wait for the thread to create the pipe(if it times out terminate) if (hSem) { if (WaitForSingleObject(hSem, 500) != WAIT_OBJECT_0) { BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. WaitForSingleObject failed", ERROR_ACCESS_DENIED); } } else { Sleep(500); } // start the elevator service (if it doesnt start first time we need to create it and then start it). if (service_start(cpServiceName) != ERROR_SUCCESS) { dprintf("[ELEVATE] service starting failed, attempting to create"); if (service_create(cpServiceName, cServiceArgs) != ERROR_SUCCESS) { BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe. service_create failed"); } dprintf("[ELEVATE] creation of service succeeded, attempting to start"); // we dont check a return value for service_start as we expect it to fail as cmd.exe is not // a valid service and it will never signal to the service manager that is is a running service. service_start(cpServiceName); } // signal our thread to terminate if it is still running thread_sigterm(pThread); // and wait for it to terminate... thread_join(pThread); // get the exit code for our pthread dprintf("[ELEVATE] dwResult before exit code: %u", dwResult); if (!GetExitCodeThread(pThread->handle, &dwResult)) { BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. GetExitCodeThread failed", ERROR_INVALID_HANDLE); } dprintf("[ELEVATE] dwResult after exit code: %u", dwResult); } while (0);
static int tar_cmd_itr(const HWND hwnd, LPCSTR szCmdLine,LPSTR szOutput, const DWORD dwSize,CTar32CmdInfo &cmdinfo) { if(cmdinfo.arcfile.empty()){ throw CTar32Exception("Archive File is not specified.", ERROR_NOT_ARC_FILE); } if(cmdinfo.argfiles.empty()){ if(cmdinfo.command == 'x' || cmdinfo.command == 'l'){ // If no file to extract/create is specified, I assume as all file is specified. cmdinfo.argfiles.push_back(CTar32CmdInfo::CArgs("*",cmdinfo.current_directory)); }else{ throw CTar32Exception("no file to archive is specified.", ERROR_NOT_ARC_FILE); } } if(cmdinfo.b_archive_tar){ switch(cmdinfo.archive_type){ case ARCHIVETYPE_NORMAL: cmdinfo.archive_type = ARCHIVETYPE_TAR;break; case ARCHIVETYPE_GZ: cmdinfo.archive_type = ARCHIVETYPE_TARGZ;break; case ARCHIVETYPE_Z: cmdinfo.archive_type = ARCHIVETYPE_TARZ;break; case ARCHIVETYPE_BZ2: cmdinfo.archive_type = ARCHIVETYPE_TARBZ2;break; case ARCHIVETYPE_LZMA: cmdinfo.archive_type = ARCHIVETYPE_TARLZMA;break; case ARCHIVETYPE_XZ: cmdinfo.archive_type = ARCHIVETYPE_TARXZ;break; } } //string arcfile = *argi++; //list<string> files(argi,args.end()); //CTar32CmdInfo cmdinfo; //cmdinfo.arcfile = arcfile; //cmdinfo.files = files; /* CTar32StatusDialog dlg; if(cmdinfo.b_display_dialog){ cmdinfo.hTar32StatusDialog = dlg.Create(hwnd); } switch(command){ case 'x': cmd_extract(cmdinfo); break; case 'c': cmd_create(cmdinfo); break; case 'l': cmd_list(cmdinfo); break; default: throw CTar32Exception("Command not specified.", ERROR_COMMAND_NAME); } */ //cmdinfo.command = command; cmdinfo.hParentWnd = hwnd; int func_ret = 0; // extern static void _cdecl tar_cmd_main_thread(LPVOID param); //DWORD process_id,thread_id; //thread_id = GetWindowThreadProcessId(hwnd,&process_id); if(cmdinfo.b_message_loop && cmdinfo.hParentWnd /*&& process_id == GetCurrentProcessId() && thread_id == GetCurrentThreadId()*/){ cmdinfo.wm_main_thread_end = RegisterWindowMessage("wm_main_thread_end"); cmdinfo.idMessageThread = GetCurrentThreadId(); MSG msg; HANDLE hThread = (HANDLE)_beginthread(tar_cmd_main_thread,0,(void*)&cmdinfo); while(GetMessage(&msg,NULL,0,0)){ if(msg.message == cmdinfo.wm_main_thread_end){ unsigned long exitcode; while(GetExitCodeThread(hThread,&exitcode) && (exitcode==STILL_ACTIVE)){ Sleep(1); } break; } if(!IsDialogMessage(cmdinfo.hTar32StatusDialog,&msg)){ TranslateMessage(&msg); DispatchMessage(&msg); } } }else{ /*func_ret =*/ tar_cmd_main_thread((LPVOID)&cmdinfo); } if(cmdinfo.exception.m_code != 0){ throw cmdinfo.exception; } return func_ret; }
EASYHOOK_NT_EXPORT RhInjectLibrary( ULONG InTargetPID, ULONG InWakeUpTID, ULONG InInjectionOptions, WCHAR* InLibraryPath_x86, WCHAR* InLibraryPath_x64, PVOID InPassThruBuffer, ULONG InPassThruSize) { /* Description: Injects a library into the target process. This is a very stable operation. The problem so far is, that only the NET layer will support injection through WOW64 boundaries and into other terminal sessions. It is quite complex to realize with unmanaged code and that's why it is not supported! If you really need this feature I highly recommend to at least look at C++.NET because using the managed injection can speed up your development progress about orders of magnitudes. I know by experience that writing the required multi-process injection code in any unmanaged language is a rather daunting task! Parameters: - InTargetPID The process in which the library should be injected. - InWakeUpTID If the target process was created suspended (RhCreateAndInject), then this parameter should be set to the main thread ID of the target. You may later resume the process from within the injected library by calling RhWakeUpProcess(). If the process is already running, you should specify zero. - InInjectionOptions All flags can be combined. EASYHOOK_INJECT_DEFAULT: No special behavior. The given libraries are expected to be unmanaged DLLs. Further they should export an entry point named "NativeInjectionEntryPoint" (in case of 64-bit) and "_NativeInjectionEntryPoint@4" (in case of 32-bit). The expected entry point signature is REMOTE_ENTRY_POINT. EASYHOOK_INJECT_MANAGED: The given user library is a NET assembly. Further they should export a class named "EasyHook.InjectionLoader" with a static method named "Main". The signature of this method is expected to be "int (String)". Please refer to the managed injection loader of EasyHook for more information about writing such managed entry points. EASYHOOK_INJECT_STEALTH: Uses the experimental stealth thread creation. If it fails you may try it with default settings. EASYHOOK_INJECT_HEART_BEAT: Is only used internally to workaround the managed process creation bug. For curiosity, NET seems to hijack our remote thread if a managed process is created suspended. It doesn't do anything with the suspended main thread, - InLibraryPath_x86 A relative or absolute path to the 32-bit version of the user library being injected. If you don't want to inject into 32-Bit processes, you may set this parameter to NULL. - InLibraryPath_x64 A relative or absolute path to the 64-bit version of the user library being injected. If you don't want to inject into 64-Bit processes, you may set this parameter to NULL. - InPassThruBuffer An optional buffer containg data to be passed to the injection entry point. Such data is available in both, the managed and unmanaged user library entry points. Set to NULL if no used. - InPassThruSize Specifies the size in bytes of the pass thru data. If "InPassThruBuffer" is NULL, this parameter shall also be zero. Returns: */ HANDLE hProc = NULL; HANDLE hRemoteThread = NULL; HANDLE hSignal = NULL; UCHAR* RemoteInjectCode = NULL; LPREMOTE_INFO Info = NULL; LPREMOTE_INFO RemoteInfo = NULL; ULONG RemoteInfoSize = 0; BYTE* Offset = 0; ULONG CodeSize; BOOL Is64BitTarget; NTSTATUS NtStatus; LONGLONG Diff; HANDLE Handles[2]; ULONG UserLibrarySize; ULONG PATHSize; ULONG EasyHookPathSize; ULONG EasyHookEntrySize; ULONG Code; SIZE_T BytesWritten; WCHAR UserLibrary[MAX_PATH+1]; WCHAR PATH[MAX_PATH + 1]; WCHAR EasyHookPath[MAX_PATH + 1]; #ifdef _M_X64 CHAR* EasyHookEntry = "HookCompleteInjection"; #else CHAR* EasyHookEntry = "_HookCompleteInjection@4"; #endif // validate parameters if(InPassThruSize > MAX_PASSTHRU_SIZE) THROW(STATUS_INVALID_PARAMETER_7, L"The given pass thru buffer is too large."); if(InPassThruBuffer != NULL) { if(!IsValidPointer(InPassThruBuffer, InPassThruSize)) THROW(STATUS_INVALID_PARAMETER_6, L"The given pass thru buffer is invalid."); } else if(InPassThruSize != 0) THROW(STATUS_INVALID_PARAMETER_7, L"If no pass thru buffer is specified, the pass thru length also has to be zero."); if(InTargetPID == GetCurrentProcessId()) THROW(STATUS_NOT_SUPPORTED, L"For stability reasons it is not supported to inject into the calling process."); // open target process if((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, InTargetPID)) == NULL) { if(GetLastError() == ERROR_ACCESS_DENIED) THROW(STATUS_ACCESS_DENIED, L"Unable to open target process. Consider using a system service.") else THROW(STATUS_NOT_FOUND, L"The given target process does not exist!"); } /* Check bitness... After this we can assume hooking a target that is running in the same WOW64 level. */ #ifdef _M_X64 FORCE(RhIsX64Process(InTargetPID, &Is64BitTarget)); if(!Is64BitTarget) THROW(STATUS_WOW_ASSERTION, L"It is not supported to directly hook through the WOW64 barrier."); if(!GetFullPathNameW(InLibraryPath_x64, MAX_PATH, UserLibrary, NULL)) THROW(STATUS_INVALID_PARAMETER_5, L"Unable to get full path to the given 64-bit library."); #else FORCE(RhIsX64Process(InTargetPID, &Is64BitTarget)); if(Is64BitTarget) THROW(STATUS_WOW_ASSERTION, L"It is not supported to directly hook through the WOW64 barrier."); if(!GetFullPathNameW(InLibraryPath_x86, MAX_PATH, UserLibrary, NULL)) THROW(STATUS_INVALID_PARAMETER_4, L"Unable to get full path to the given 32-bit library."); #endif /* Validate library path... */ if(!RtlFileExists(UserLibrary)) { #ifdef _M_X64 THROW(STATUS_INVALID_PARAMETER_5, L"The given 64-Bit library does not exist!"); #else THROW(STATUS_INVALID_PARAMETER_4, L"The given 32-Bit library does not exist!"); #endif } // import strings... RtlGetWorkingDirectory(PATH, MAX_PATH - 1); RtlGetCurrentModulePath(EasyHookPath, MAX_PATH); // allocate remote information block EasyHookPathSize = (RtlUnicodeLength(EasyHookPath) + 1) * 2; EasyHookEntrySize = (RtlAnsiLength(EasyHookEntry) + 1); PATHSize = (RtlUnicodeLength(PATH) + 1 + 1) * 2; UserLibrarySize = (RtlUnicodeLength(UserLibrary) + 1 + 1) * 2; PATH[PATHSize / 2 - 2] = ';'; PATH[PATHSize / 2 - 1] = 0; RemoteInfoSize = EasyHookPathSize + EasyHookEntrySize + PATHSize + InPassThruSize + UserLibrarySize; RemoteInfoSize += sizeof(REMOTE_INFO); if((Info = (LPREMOTE_INFO)RtlAllocateMemory(TRUE, RemoteInfoSize)) == NULL) THROW(STATUS_NO_MEMORY, L"Unable to allocate memory in current process."); Info->LoadLibraryW = (PVOID)GetProcAddress(hKernel32, "LoadLibraryW"); Info->FreeLibrary = (PVOID)GetProcAddress(hKernel32, "FreeLibrary"); Info->GetProcAddress = (PVOID)GetProcAddress(hKernel32, "GetProcAddress"); Info->VirtualFree = (PVOID)GetProcAddress(hKernel32, "VirtualFree"); Info->VirtualProtect = (PVOID)GetProcAddress(hKernel32, "VirtualProtect"); Info->ExitThread = (PVOID)GetProcAddress(hKernel32, "ExitThread"); Info->GetLastError = (PVOID)GetProcAddress(hKernel32, "GetLastError"); Info->WakeUpThreadID = InWakeUpTID; Info->IsManaged = InInjectionOptions & EASYHOOK_INJECT_MANAGED; // allocate memory in target process CodeSize = GetInjectionSize(); if((RemoteInjectCode = (BYTE*)VirtualAllocEx(hProc, NULL, CodeSize + RemoteInfoSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL) THROW(STATUS_NO_MEMORY, L"Unable to allocate memory in target process."); // save strings Offset = (BYTE*)(Info + 1); Info->EasyHookEntry = (char*)Offset; Info->EasyHookPath = (wchar_t*)(Offset += EasyHookEntrySize); Info->PATH = (wchar_t*)(Offset += EasyHookPathSize); Info->UserData = (BYTE*)(Offset += PATHSize); Info->UserLibrary = (WCHAR*)(Offset += InPassThruSize); Info->Size = RemoteInfoSize; Info->HostProcess = GetCurrentProcessId(); Info->UserDataSize = 0; Offset += UserLibrarySize; if((ULONG)(Offset - ((BYTE*)Info)) > Info->Size) THROW(STATUS_BUFFER_OVERFLOW, L"A buffer overflow in internal memory was detected."); RtlCopyMemory(Info->EasyHookPath, EasyHookPath, EasyHookPathSize); RtlCopyMemory(Info->PATH, PATH, PATHSize); RtlCopyMemory(Info->EasyHookEntry, EasyHookEntry, EasyHookEntrySize); RtlCopyMemory(Info->UserLibrary, UserLibrary, UserLibrarySize); if(InPassThruBuffer != NULL) { RtlCopyMemory(Info->UserData, InPassThruBuffer, InPassThruSize); Info->UserDataSize = InPassThruSize; } // copy code into target process if(!WriteProcessMemory(hProc, RemoteInjectCode, GetInjectionPtr(), CodeSize, &BytesWritten) || (BytesWritten != CodeSize)) THROW(STATUS_INTERNAL_ERROR, L"Unable to write into target process memory."); // create and export signal event> if((hSignal = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) THROW(STATUS_INSUFFICIENT_RESOURCES, L"Unable to create event."); // Possible resource leck: the remote handles cannt be closed here if an error occurs if(!DuplicateHandle(GetCurrentProcess(), hSignal, hProc, &Info->hRemoteSignal, EVENT_ALL_ACCESS, FALSE, 0)) THROW(STATUS_INTERNAL_ERROR, L"Failed to duplicate remote event."); // relocate remote information RemoteInfo = (LPREMOTE_INFO)(RemoteInjectCode + CodeSize); Diff = ((BYTE*)RemoteInfo - (BYTE*)Info); Info->EasyHookEntry = (char*)(((BYTE*)Info->EasyHookEntry) + Diff); Info->EasyHookPath = (wchar_t*)(((BYTE*)Info->EasyHookPath) + Diff); Info->PATH = (wchar_t*)(((BYTE*)Info->PATH) + Diff); Info->UserLibrary = (wchar_t*)(((BYTE*)Info->UserLibrary) + Diff); if(Info->UserData != NULL) Info->UserData = (BYTE*)(((BYTE*)Info->UserData) + Diff); Info->RemoteEntryPoint = RemoteInjectCode; if(!WriteProcessMemory(hProc, RemoteInfo, Info, RemoteInfoSize, &BytesWritten) || (BytesWritten != RemoteInfoSize)) THROW(STATUS_INTERNAL_ERROR, L"Unable to write into target process memory."); if((InInjectionOptions & EASYHOOK_INJECT_STEALTH) != 0) { FORCE(RhCreateStealthRemoteThread(InTargetPID, (LPTHREAD_START_ROUTINE)RemoteInjectCode, RemoteInfo, &hRemoteThread)); } else { if(!RTL_SUCCESS(NtCreateThreadEx(hProc, (LPTHREAD_START_ROUTINE)RemoteInjectCode, RemoteInfo, FALSE, &hRemoteThread))) { // create remote thread and wait for injection completion if((hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)RemoteInjectCode, RemoteInfo, 0, NULL)) == NULL) THROW(STATUS_ACCESS_DENIED, L"Unable to create remote thread."); } } /* * The assembler codes are designed to let us derive extensive error information... */ Handles[1] = hSignal; Handles[0] = hRemoteThread; Code = WaitForMultipleObjects(2, Handles, FALSE, INFINITE); if(Code == WAIT_OBJECT_0) { // parse error code GetExitCodeThread(hRemoteThread, &Code); SetLastError(Code & 0x0FFFFFFF); switch(Code & 0xF0000000) { case 0x10000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to find internal entry point."); case 0x20000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to make stack executable."); case 0x30000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to release injected library."); case 0x40000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to find EasyHook library in target process context."); case 0xF0000000: // error in C++ injection completion { switch(Code & 0xFF) { #ifdef _M_X64 case 20: THROW(STATUS_INVALID_PARAMETER_5, L"Unable to load the given 64-bit library into target process."); case 21: THROW(STATUS_INVALID_PARAMETER_5, L"Unable to find the required native entry point in the given 64-bit library."); case 12: THROW(STATUS_INVALID_PARAMETER_5, L"Unable to find the required managed entry point in the given 64-bit library."); #else case 20: THROW(STATUS_INVALID_PARAMETER_4, L"Unable to load the given 32-bit library into target process."); case 21: THROW(STATUS_INVALID_PARAMETER_4, L"Unable to find the required native entry point in the given 32-bit library."); case 12: THROW(STATUS_INVALID_PARAMETER_4, L"Unable to find the required managed entry point in the given 32-bit library."); #endif case 13: THROW(STATUS_DLL_INIT_FAILED, L"The user defined managed entry point failed in the target process. Make sure that EasyHook is registered in the GAC. Refer to event logs for more information."); case 1: THROW(STATUS_INTERNAL_ERROR, L"Unable to allocate memory in target process."); case 2: THROW(STATUS_INTERNAL_ERROR, L"Unable to adjust target's PATH variable."); case 10: THROW(STATUS_INTERNAL_ERROR, L"Unable to load 'mscoree.dll' into target process."); case 11: THROW(STATUS_INTERNAL_ERROR, L"Unable to bind NET Runtime to target process."); case 22: THROW(STATUS_INTERNAL_ERROR, L"Unable to signal remote event."); default: THROW(STATUS_INTERNAL_ERROR, L"Unknown error in injected C++ completion routine."); } }break; case 0: THROW(STATUS_INTERNAL_ERROR, L"C++ completion routine has returned success but didn't raise the remote event."); default: THROW(STATUS_INTERNAL_ERROR, L"Unknown error in injected assembler code."); } } else if(Code != WAIT_OBJECT_0 + 1) THROW(STATUS_INTERNAL_ERROR, L"Unable to wait for injection completion due to timeout. "); RETURN; THROW_OUTRO: FINALLY_OUTRO: { // release resources if(hProc != NULL) CloseHandle(hProc); if(Info != NULL) RtlFreeMemory(Info); if(hRemoteThread != NULL) CloseHandle(hRemoteThread); if(hSignal != NULL) CloseHandle(hSignal); return NtStatus; } }
HANDLE __stdcall DllInjectionW(PROCESS_INFORMATION *pi, //プロセスの情報 const wchar_t *szDllName)//Dllファイル名 { HANDLE hProcess = pi->hProcess; //dllファイルの絶対パスを保存する変数 TCHAR szLibFile[MAX_PATH]; //dllファイルの絶対パスの文字列の長さ + 1(\0までの長さを保存する) int szLibFileLen; //もし相対パスなら、 //自身の絶対パスの取得をして、dllまでの絶対パスを作る。 //(例 X:/-----/--.... というパスは、1バイト目が':'なので、絶対パスとなる。) //絶対パスなら、そのままコピーするだけ。 if(szDllName[1] != ':'){ GetModuleFileName(NULL, szLibFile, sizeof(szLibFile)); lstrcpy(_tcsrchr(szLibFile, _TEXT('\\')) + 1, szDllName); } else { lstrcpyW(szLibFile,szDllName); } //長さ(使うメモリ領域)の計算 szLibFileLen = lstrlen(szLibFile) + 1; szLibFileLen = szLibFileLen * sizeof(TCHAR); //プロセス内にメモリ領域の確保 LPSTR RemoteProcessMemory; RemoteProcessMemory = (LPSTR)VirtualAllocEx( hProcess, NULL, szLibFileLen, MEM_COMMIT, PAGE_READWRITE); if(RemoteProcessMemory == NULL){ //setErrorString("プロセス内にメモリが確保できませんでした。"); return NULL; } //書き込み if(WriteProcessMemory(hProcess, RemoteProcessMemory, (PVOID)szLibFile, szLibFileLen, NULL) == 0){ //setErrorString("プロセスに書き込みができませんでした。"); return NULL; } //LoadLibraryW関数が始まるポインタの取得 PTHREAD_START_ROUTINE pfnThreadRtn; pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress( GetModuleHandle(_TEXT("Kernel32")), "LoadLibraryW"); if (pfnThreadRtn == NULL){ //setErrorString("LoadLibraryが見つかりませんでした。(何故?)"); return NULL; } //スレッド作成 HANDLE hThread; hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, RemoteProcessMemory,CREATE_SUSPENDED, NULL); if (hThread == NULL){ //setErrorString("スレッドが作れませんでした。"); return NULL; } //スレッド実行 ResumeThread(hThread); BYTE *modulePointer = (BYTE *)WaitForSingleObject(hThread,INFINITE); DWORD dwExitCode; //終了コード GetExitCodeThread(hThread,&dwExitCode); CloseHandle(hThread); //スレッドを閉じる //プロセス内に確保したメモリの開放 VirtualFreeEx(hProcess,RemoteProcessMemory,260,MEM_DECOMMIT); if(dwExitCode == NULL){ char a_szLibName[MAX_PATH]; BOOL bDummy; WideCharToMultiByte(CP_ACP,0,szLibFile,-1,a_szLibName,MAX_PATH,"<不明なライブラリ>",&bDummy); //setErrorStringEx("%s ---- DLLがロードできませんでした。",a_szLibName); return NULL; } return (HANDLE)dwExitCode; }
BOOL ForceLibraryNT(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo) { sLibLoadCodeNT LibLoadCode; DWORD dwRemoteThreadID; HANDLE hRemoteThread; _CodeEntry CodeEntry; // import NT only stuff manually HMODULE kernel = GetModuleHandle("kernel32.dll"); typedef LPVOID (WINAPI*VirtualAllocExFunc)( HANDLE hProcess, // process to allocate memory LPVOID lpAddress, // desired starting address SIZE_T dwSize, // size of region to allocate DWORD flAllocationType, // type of allocation DWORD flProtect // type of access protection ); VirtualAllocExFunc VirtualAllocExPtr = (VirtualAllocExFunc)GetProcAddress(kernel,"VirtualAllocEx"); typedef BOOL (WINAPI*VirtualFreeExFunc)( HANDLE hProcess, // handle to process LPVOID lpAddress, // starting address of memory region SIZE_T dwSize, // size of memory region DWORD dwFreeType // operation type ); VirtualFreeExFunc VirtualFreeExPtr = (VirtualFreeExFunc)GetProcAddress(kernel,"VirtualFreeEx"); if(!VirtualFreeExPtr || !VirtualAllocExPtr) { //MessageBox(0,"couldnt import virtualallocex",0,0); printf("couldnt import virtualallocex\n"); ExitProcess(1); } // get some mem in the target's process memory dwCodeStart = (DWORD)VirtualAllocExPtr( pProcInfo->hProcess, NULL, sizeof(LibLoadCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!dwCodeStart) return FALSE; // init the LibLoadCode struct if (!InitCodeStruct(0, &LibLoadCode, szLibraryPath, dwCodeStart)) { VirtualFreeExPtr( pProcInfo->hProcess, (VOID*)dwCodeStart, sizeof(LibLoadCode), MEM_DECOMMIT); return FALSE; } // copy the code into the allocated mem if (!WriteProcessMemory( pProcInfo->hProcess, (VOID*)dwCodeStart, &LibLoadCode, sizeof(LibLoadCode), &dwBytesWritten)) { VirtualFreeExPtr( pProcInfo->hProcess, (VOID*)dwCodeStart, sizeof(LibLoadCode), MEM_DECOMMIT); return FALSE; } // execute it CodeEntry = (_CodeEntry)dwCodeStart; if (!(hRemoteThread = CreateRemoteThread( pProcInfo->hProcess, NULL, 0, CodeEntry, NULL, 0, &dwRemoteThreadID))) { VirtualFreeExPtr( pProcInfo->hProcess, (VOID*)dwCodeStart, sizeof(LibLoadCode), MEM_DECOMMIT); return FALSE; } // wait until the thread finishes WaitForSingleObject(hRemoteThread, INFINITE); if (!GetExitCodeThread(hRemoteThread, &dwLibBase)) { VirtualFreeExPtr( pProcInfo->hProcess, (VOID*)dwCodeStart, sizeof(LibLoadCode), MEM_DECOMMIT); return FALSE; } // clean up VirtualFreeExPtr( pProcInfo->hProcess, (VOID*)dwCodeStart, sizeof(LibLoadCode), MEM_DECOMMIT); CloseHandle(hRemoteThread); if (dwLibBase) return TRUE; else return FALSE; }
static int exm_dll_inject(Exm *exm) { STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE process; HANDLE remote_thread; LPVOID remote_string; DWORD exit_code; /* actually the base address of the mapped DLL */ ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); printf(" * creating child process %s... ", exm->filename); if (!CreateProcess(NULL, exm->filename, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { printf("failed\n * can't spawn child process %s\n", exm->filename); return 0; } printf("done\n"); printf(" * waiting for the child process to initialize... "); if (!WaitForInputIdle(pi.hProcess, INFINITE)) { printf("failed\n * no process for %s\n", exm->filename); goto close_handles; } printf("done\n"); printf(" * opening child process... "); process = OpenProcess(CREATE_THREAD_ACCESS, FALSE, pi.dwProcessId); if (!process) { printf("failed\n * no process for %s\n", exm->filename); goto close_handles; } printf("done\n"); printf(" * mapping process handle 0x%p... ", pi.hProcess); exm->map_process.handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(HANDLE), "shared_process_handle"); if (!exm->map_process.handle) { printf("failed\n"); goto close_process; } exm->map_process.base = MapViewOfFile(exm->map_process.handle, FILE_MAP_WRITE, 0, 0, sizeof(HANDLE)); if (!exm->map_process.base) { printf("failed\n"); goto close_process_handle; } CopyMemory(exm->map_process.base, &pi.hProcess, sizeof(HANDLE)); printf("done\n"); printf(" * allocating virtual memory... "); remote_string = VirtualAllocEx(process, NULL, exm->dll_length, MEM_COMMIT, PAGE_READWRITE); if (!remote_string) { printf("failed\n"); goto unmap_process_handle; } printf("done\n"); printf(" * writing process in virtual memory... "); if (!WriteProcessMemory(process, remote_string, exm->dll_fullname, exm->dll_length, NULL)) { printf("failed\n"); goto virtual_free; } printf("done\n"); printf(" * execute thread... "); remote_thread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)exm->ll, remote_string, 0, NULL); if (!remote_thread) { printf("failed\n"); goto virtual_free; } printf("done\n"); WaitForSingleObject(remote_thread, INFINITE); printf(" * getting exit code... "); if (!GetExitCodeThread(remote_thread, &exit_code)) { printf("failed\n"); goto close_thread; } printf("done\n"); CloseHandle(remote_thread); VirtualFreeEx(process, remote_string, 0, MEM_RELEASE); printf(" * resume child process\n"); ResumeThread(pi.hThread); exm->child.process1 = pi.hProcess; exm->child.thread = pi.hThread; exm->child.process2 = process; exm->exit_code = exit_code; return 1; close_thread: CloseHandle(remote_thread); virtual_free: VirtualFreeEx(process, remote_string, 0, MEM_RELEASE); unmap_process_handle: UnmapViewOfFile(exm->map_process.base); close_process_handle: CloseHandle(exm->map_process.handle); close_process: CloseHandle(process); close_handles: CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return 0; }
// Simple app to inject a reflective DLL into a process vis its process ID. int WinMain() //int argc, char * argv[] { HANDLE hFile = NULL; HANDLE hModule = NULL; HANDLE hProcess = NULL; HANDLE hToken = NULL; LPVOID lpBuffer = NULL; DWORD dwLength = 0; DWORD dwBytesRead = 0; DWORD dwProcessId = 0; DWORD dwExitCode = 1; TOKEN_PRIVILEGES priv = {0}; #ifdef WIN_X64 char * cpDllFile = "reflective_dll.x64.dll"; #else char * cpDllFile = "reflective_dll.dll"; #endif do { // Usage: inject.exe [string] [pid] [dll_file] //if (argc == 2) // dwProcessId = GetCurrentProcessId(); //else //dwProcessId = atoi( argv[2] ); dwProcessId = getPid("ffxiv_dx11.exe"); //if( argc >= 4 ) // cpDllFile = argv[3]; cpDllFile = "ffxiv-fixfullscreen.dll"; hFile = CreateFileA( cpDllFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) BREAK_WITH_ERROR( "Failed to open the DLL file" ); dwLength = GetFileSize( hFile, NULL ); if( dwLength == INVALID_FILE_SIZE || dwLength == 0 ) BREAK_WITH_ERROR( "Failed to get the DLL file size" ); lpBuffer = HeapAlloc( GetProcessHeap(), 0, dwLength ); if( !lpBuffer ) BREAK_WITH_ERROR( "Failed to get the DLL file size" ); if( ReadFile( hFile, lpBuffer, dwLength, &dwBytesRead, NULL ) == FALSE ) BREAK_WITH_ERROR( "Failed to alloc a buffer!" ); if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) { priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) ) AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL ); CloseHandle( hToken ); } hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessId ); if( !hProcess ) BREAK_WITH_ERROR( "Failed to open the target process" ); hModule = LoadRemoteLibraryR( hProcess, lpBuffer, dwLength, NULL, MYFUNCTION_HASH, "user data", 1337); // originally (DWORD)(strlen(argv[1]) + 1) if( !hModule ) BREAK_WITH_ERROR( "Failed to inject the DLL" ); //printf( "[+] Injected the '%s' DLL into process %d.\n", cpDllFile, dwProcessId ); WaitForSingleObject( hModule, -1 ); if ( !GetExitCodeThread( hModule, &dwExitCode ) ) BREAK_WITH_ERROR( "Failed to get exit code of thread" ); //printf( "[+] Created thread exited with code %d.\n", dwExitCode ); //char message[260] = "Injection successful. Thread exited with code: "; //char buffer[260]; //sprintf(buffer, "%d", dwExitCode); //MessageBox(0, strcat(message, buffer), "Info", 1); } while( 0 ); if( lpBuffer ) HeapFree( GetProcessHeap(), 0, lpBuffer ); if( hProcess ) CloseHandle( hProcess ); return dwExitCode; }
DWORD WINAPI f_send(void*) { char *pseudo; char *text; t_str *chain; SOCKADDR_IN server; DWORD ExitCode; chain = NULL; ExitCode = 0; pseudo = f_capture_pseudo(); printf("Pseudo : %s\n", pseudo); printf("Connection en cours...\n"); s_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr("192.168.1.32"); // pensez bien à préciser ici l'adresse de votre serveur server.sin_port = htons(4242); memset(&server.sin_zero, '\0', sizeof(server.sin_zero)); while (connect(s_socket, (SOCKADDR *)&server, sizeof(server)) == SOCKET_ERROR) { printf("Connexion impossible\nNouvel essai...\n"); Sleep(400); connected = 0; } connected = 1; printf("\t-------- Connexion etablie --------\n"); if (send(s_socket, pseudo, (int)strlen(pseudo), 0) == SOCKET_ERROR) { printf("Erreur de transmission de donnees\n"); system("PAUSE"); return (0); } else { printf("Tapez \"EXIT PROGRAM\" pour quitter le programme\n"); while (1) { text = f_capture_text(); if (f_exit_client(text) == 0) { chain = add_str(chain, text, 0); chain = add_str(chain, 0, '\n'); text = export_str(chain); if (send(s_socket, text, cpt_index(chain) - 1, 0) == SOCKET_ERROR) { printf("Erreur de transmission de donnees\n"); system("PAUSE"); system("EXIT"); return (0); } chain = free_list(chain); } else { connected = 0; printf("Deconnection...\n"); shutdown(s_socket, SD_SEND); closesocket(s_socket); WSACleanup(); printf("Fermeture du client en court...\n"); Sleep(300); printf("Le programme va se fermer...\n"); Sleep(300); quit = 1; GetExitCodeThread(GetCurrentThread(), &ExitCode); ExitThread(ExitCode); return (0); } } } return (0); }