enum procerr procRun(unsigned xnargs, char * const xargs[], int * rc) { STARTUPINFOW si; PROCESS_INFORMATION pi; enum procerr err = ERR_PROC_OK; DWORD drc = 0; WCHAR args[MAXCMD]; LPWSTR cl = GetCommandLineW(); int argc; LPWSTR * wargv = CommandLineToArgvW(cl, &argc); argvToCommandLine(args, argc-4, wargv+4); LocalFree(wargv); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); CHK(ERR_PROC_FORK, !CreateProcessW(0, args, 0, 0, 0, CREATE_SUSPENDED, 0, 0, &si, &pi)); if (err == ERR_PROC_OK) injectProcess(pi.hProcess); CHK(ERR_PROC_EXEC, -1 == ResumeThread(pi.hThread)); CHK(ERR_PROC_WAIT, WAIT_OBJECT_0 != WaitForSingleObject(pi.hThread, INFINITE)); CHK(ERR_PROC_WAIT, WAIT_OBJECT_0 != WaitForSingleObject(pi.hProcess, INFINITE)); CHK(ERR_PROC_WAIT, !GetExitCodeProcess(pi.hProcess, &drc)); CHK(ERR_PROC_FORK, !CloseHandle(pi.hThread)); CHK(ERR_PROC_FORK, !CloseHandle(pi.hProcess)); if (err == ERR_PROC_OK) *rc = drc; return err; }
BOOL WINAPI CreateProcessHooked(LPCWSTR lpApplicationName , LPWSTR lpCommandLine , LPSECURITY_ATTRIBUTES lpProcessAttributes , LPSECURITY_ATTRIBUTES lpThreadAttributes , BOOL bInheritHandles , DWORD dwCreationFlags , LPVOID lpEnvironment , LPCWSTR lpCurrentDirectory , LPSTARTUPINFOW lpStartupInfo , LPPROCESS_INFORMATION lpProcessInformation) { BOOL susp = dwCreationFlags & CREATE_SUSPENDED; DWORD flags = dwCreationFlags | CREATE_SUSPENDED; BOOL res = CreateProcessW(lpApplicationName, lpCommandLine , lpProcessAttributes, lpThreadAttributes , bInheritHandles, flags , lpEnvironment, lpCurrentDirectory , lpStartupInfo, lpProcessInformation); if (!res) { spdlog::get("usvfs")->error("failed to spawn {}", ush::string_cast<std::string>(lpCommandLine)); return FALSE; } std::wstring applicationDirPath = winapi::wide::getModuleFileName(dllModule); boost::filesystem::path p(applicationDirPath); try { injectProcess(p.parent_path().wstring() , context->callParameters() , *lpProcessInformation); } catch (const std::exception &e) { spdlog::get("usvfs")->error("failed to inject: {}", e.what()); logExtInfo(e, LogLevel::Error); ::TerminateProcess(lpProcessInformation->hProcess, 1); ::SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (!susp) { ResumeThread(lpProcessInformation->hThread); } return TRUE; }
void injectPID(DWORD pid) { HANDLE h; CHK(0 != (h = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid))); injectProcess(h); CHK(CloseHandle(h)); }