std::unique_ptr<Host> Host::Create(const tchar_t* path, const tchar_t* arguments, HANDLE handles[], size_t numhandles) { PROCESS_INFORMATION procinfo; // Process information // If a null argument string was provided, change it to an empty string if(arguments == nullptr) arguments = _T(""); // Generate the command line for the child process, using the specifed path as argument zero tchar_t commandline[MAX_PATH]; _sntprintf_s(commandline, MAX_PATH, MAX_PATH, _T("\"%s\"%s%s"), path, (arguments[0]) ? _T(" ") : _T(""), arguments); // Determine the size of the attributes buffer required to hold the inheritable handles property SIZE_T required = 0; InitializeProcThreadAttributeList(nullptr, 1, 0, &required); if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) throw Win32Exception(); // Allocate a buffer large enough to hold the attribute data and initialize it HeapBuffer<uint8_t> buffer(required); PPROC_THREAD_ATTRIBUTE_LIST attributes = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(&buffer); if(!InitializeProcThreadAttributeList(attributes, 1, 0, &required)) throw Win32Exception(); try { // UpdateProcThreadAttribute will fail if there are no handles in the specified array if((handles != nullptr) && (numhandles > 0)) { // Add the array of handles as inheritable handles for the client process if(!UpdateProcThreadAttribute(attributes, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handles, numhandles * sizeof(HANDLE), nullptr, nullptr)) throw Win32Exception(); } // Attempt to launch the process using the CREATE_SUSPENDED and EXTENDED_STARTUP_INFO_PRESENT flag zero_init<STARTUPINFOEX> startinfo; startinfo.StartupInfo.cb = sizeof(STARTUPINFOEX); startinfo.lpAttributeList = attributes; if(!CreateProcess(path, commandline, nullptr, nullptr, TRUE, CREATE_SUSPENDED | EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, &startinfo.StartupInfo, &procinfo)) throw Win32Exception(); DeleteProcThreadAttributeList(attributes); // Clean up the PROC_THREAD_ATTRIBUTE_LIST } catch(...) { DeleteProcThreadAttributeList(attributes); throw; } // Process was successfully created and initialized, pass it off to a Host instance return std::make_unique<Host>(procinfo); }
HRESULT AppContainerLauncherProcess(LPCWSTR app,LPCWSTR cmdArgs,LPCWSTR workDir) { wchar_t appContainerName[]=L"Phoenix.Container.AppContainer.Profile.v1.test"; wchar_t appContainerDisplayName[]=L"Phoenix.Container.AppContainer.Profile.v1.test\0"; wchar_t appContainerDesc[]=L"Phoenix Container Default AppContainer Profile Test,Revision 1\0"; DeleteAppContainerProfile(appContainerName);///Remove this AppContainerProfile std::vector<SID_AND_ATTRIBUTES> capabilities; std::vector<SHARED_SID> capabilitiesSidList; if(!MakeWellKnownSIDAttributes(capabilities,capabilitiesSidList)) return S_FALSE; PSID sidImpl; HRESULT hr=::CreateAppContainerProfile(appContainerName, appContainerDisplayName, appContainerDesc, (capabilities.empty() ? NULL : &capabilities.front()), capabilities.size(), &sidImpl); if(hr!=S_OK){ std::cout<<"CreateAppContainerProfile Failed"<<std::endl; return hr; } wchar_t *psArgs=nullptr; psArgs=_wcsdup(cmdArgs); PROCESS_INFORMATION pi; STARTUPINFOEX siex = { sizeof(STARTUPINFOEX) }; siex.StartupInfo.cb = sizeof(STARTUPINFOEXW); SIZE_T cbAttributeListSize = 0; BOOL bReturn = InitializeProcThreadAttributeList( NULL, 3, 0, &cbAttributeListSize); siex.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize); bReturn = InitializeProcThreadAttributeList(siex.lpAttributeList, 3, 0, &cbAttributeListSize); SECURITY_CAPABILITIES sc; sc.AppContainerSid = sidImpl; sc.Capabilities = (capabilities.empty() ? NULL : &capabilities.front()); sc.CapabilityCount = capabilities.size(); sc.Reserved = 0; if(UpdateProcThreadAttribute(siex.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, &sc, sizeof(sc) , NULL, NULL)==FALSE) { goto Cleanup; } BOOL bRet=CreateProcessW(app, psArgs, nullptr, nullptr, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, workDir, reinterpret_cast<LPSTARTUPINFOW>(&siex), &pi); ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); Cleanup: DeleteProcThreadAttributeList(siex.lpAttributeList); DeleteAppContainerProfile(appContainerName); free(psArgs); FreeSid(sidImpl); return hr; }
int test_pal_thread_start( test_pal_thread_state_t *thread_state, struct test_pal_logical_processor *lp, test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state), void *thread_user_state ) { BOOL brv; DWORD thread_id; GROUP_AFFINITY ga; int rv = 0; LPPROC_THREAD_ATTRIBUTE_LIST attribute_list; SIZE_T attribute_list_length; assert( thread_state != NULL ); assert( lp != NULL ); assert( thread_function != NULL ); // TRD : thread_user_state can be NULL /* TRD : here we're using CreateRemoteThreadEx() to start a thread in our own process we do this because as a function, it allows us to specify processor and processor group affinity in the create call */ brv = InitializeProcThreadAttributeList( NULL, 1, 0, &attribute_list_length ); attribute_list = malloc( attribute_list_length ); brv = InitializeProcThreadAttributeList( attribute_list, 1, 0, &attribute_list_length ); ga.Mask = ( (KAFFINITY) 1 << lp->logical_processor_number ); ga.Group = (WORD) lp->windows_logical_processor_group_number; memset( ga.Reserved, 0, sizeof(WORD) * 3 ); brv = UpdateProcThreadAttribute( attribute_list, 0, PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY, &ga, sizeof(GROUP_AFFINITY), NULL, NULL ); *thread_state = CreateRemoteThreadEx( GetCurrentProcess(), NULL, 0, thread_function, thread_user_state, NO_FLAGS, attribute_list, &thread_id ); DeleteProcThreadAttributeList( attribute_list ); free( attribute_list ); if( *thread_state != NULL ) rv = 1; return( rv ); }
int _tmain(int argc, _TCHAR* argv[]) { bool parentprocess = false; DWORD createflags = 0; WCHAR* cmdline = nullptr; int pid = 0; int illevel = -1; if (!ParseArgs(argc, argv, &pid, &parentprocess, &createflags, &cmdline, &illevel)) { printf("NewProcessFromToken: [options] pid cmdline\n"); printf("Options:\n"); printf("-p : Use parent process technique to create the new process\n"); printf("-j : Try and break away from the current process job\n"); printf("-c : Create a new console for the process\n"); printf("-il level: Set the process IL level\n"); printf("* level:\n"); printf(" u - Untrusted\n"); printf(" l - Low\n"); printf(" m - Medium\n"); printf(" h - High\n"); printf(" s - System\n"); printf(" 0xXXXX - Arbitrary IL\n"); } else { if (pid == 0) { pid = GetCurrentProcessId(); } EnableDebugPrivilege(); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess) { if (!parentprocess) { HANDLE hToken; if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken)) { HANDLE hDupToken; if (DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, nullptr, SecurityImpersonation, TokenPrimary, &hDupToken)) { if (illevel >= 0) { SetTokenIL(hDupToken, illevel); } STARTUPINFO startInfo = { 0 }; PROCESS_INFORMATION procInfo = { 0 }; startInfo.cb = sizeof(startInfo); if (CreateProcessAsUserW(hDupToken, nullptr, cmdline, nullptr, nullptr, FALSE, createflags, nullptr, nullptr, &startInfo, &procInfo)) { printf("Created process %d\n", procInfo.dwProcessId); } else { printf("Error CreateProcessAsUser: %ls\n", GetErrorMessage().c_str()); if (CreateProcessWithTokenW(hDupToken, 0, nullptr, cmdline, createflags, nullptr, nullptr, &startInfo, &procInfo)) { printf("Created process %d\n", procInfo.dwProcessId); } else { printf("Error CreateProcessWithToken: %ls\n", GetErrorMessage().c_str()); } } } else { printf("Error Duplicating Token: %ls\n", GetErrorMessage().c_str()); } } else { printf("Error OpenProcessToken: %ls\n", GetErrorMessage().c_str()); } } else { SIZE_T size = 0; InitializeProcThreadAttributeList(nullptr, 1, 0, &size); std::vector<BYTE> attrlist(size); LPPROC_THREAD_ATTRIBUTE_LIST pattrlist = (LPPROC_THREAD_ATTRIBUTE_LIST)&attrlist[0]; InitializeProcThreadAttributeList(pattrlist, 1, 0, &size); if (UpdateProcThreadAttribute(pattrlist, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProcess, sizeof(hProcess), nullptr, nullptr)) { STARTUPINFOEX startInfo = { 0 }; PROCESS_INFORMATION procInfo = { 0 }; startInfo.StartupInfo.cb = sizeof(startInfo); startInfo.lpAttributeList = pattrlist; if (CreateProcess(nullptr, cmdline, nullptr, nullptr, FALSE, CREATE_SUSPENDED | EXTENDED_STARTUPINFO_PRESENT | createflags, nullptr, nullptr, &startInfo.StartupInfo, &procInfo)) { printf("Created process %d\n", procInfo.dwProcessId); if (illevel >= 0) { HANDLE hToken; if (OpenProcessToken(procInfo.hProcess, TOKEN_ALL_ACCESS, &hToken)) { SetTokenIL(hToken, illevel); } } ResumeThread(procInfo.hThread); } else { printf("Error: CreateProcess %ls\n", GetErrorMessage().c_str()); } } DeleteProcThreadAttributeList(pattrlist); } } else { printf("Error OpenProcess: %ls\n", GetErrorMessage().c_str()); } } return 0; }