VOID CreateProcessParameters(HANDLE hProcess,PPEB Peb,PUNICODE_STRING ImageName,PUNICODE_STRING CmdLine){ PPROCESS_PARAMETERS pp; ULONG n; PVOID p=0; UNICODE_STRING CurrentDirectory; UNICODE_STRING DllPath; RtlInitUnicodeString(&CurrentDirectory,L"C:\\WINNT\\SYSTEM32\\"); RtlInitUnicodeString(&DllPath,L"C:\\;C:\\WINNT\\;C:\\WINNT\\SYSTEM32\\"); RtlCreateProcessParameters(&pp,ImageName,&DllPath,&CurrentDirectory,CmdLine,0,0,0,0,0); pp->Environment=CopyEnvironment(hProcess); n=pp->Size; UtilsZwRoutine(ZWALLOCATE_VIRTUAL_MEMORY_INDEX,hProcess,&p,0,&n, MEM_COMMIT,PAGE_READWRITE); UtilsZwRoutine(ZWWRITE_VIRTUAL_MEMORY_INDEX,hProcess,p,pp,pp->Size,0); UtilsZwRoutine(ZWWRITE_VIRTUAL_MEMORY_INDEX,hProcess,(PCHAR)Peb+0x10,&p,sizeof(p),0); // No way i will write a clone to destroy those !@#$@! parameters :)) // Actually its only a Free().. }
VOID SepServerSpawnClientProcess(VOID) { RTL_USER_PROCESS_INFORMATION ProcessInformation; STRING ImagePathName, ProgramName; UNICODE_STRING UnicodeImagePathName, UnicodeProgramName; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; RtlInitString( &ProgramName, "\\SystemRoot\\Bin\\utlpcqos.exe" ); Status = RtlAnsiStringToUnicodeString( &UnicodeProgramName, &ProgramName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); RtlInitString( &ImagePathName, "utlpcqos.exe"); Status = RtlAnsiStringToUnicodeString( &UnicodeImagePathName, &ImagePathName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); Status = RtlCreateProcessParameters( &ProcessParameters, &ImagePathName, //UNICODEFIX &UnicodeImagePathName, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); SEASSERT_SUCCESS(Status); Status = RtlCreateUserProcess( &ProgramName, // UNICODEFIX &UnicodeProgramName, ProcessParameters, // ProcessParameters NULL, // ProcessSecurityDescriptor NULL, // ThreadSecurityDescriptor NtCurrentProcess(), // ParentProcess FALSE, // InheritHandles NULL, // DebugPort NULL, // ExceptionPort &ProcessInformation // ProcessInformation ); SEASSERT_SUCCESS(Status); Status = NtResumeThread( ProcessInformation.Thread, NULL ); SEASSERT_SUCCESS(Status); RtlDestroyProcessParameters( ProcessParameters ); RtlFreeUnicodeString( &UnicodeProgramName ); RtlFreeUnicodeString( &UnicodeImagePathName ); }
NTSTATUS CreateNativeProcess(IN PCWSTR file_name, IN PCWSTR cmd_line, OUT PHANDLE hProcess) { UNICODE_STRING fname, nt_file; PCWSTR file_part; UNICODE_STRING EnvString, NullString, UnicodeSystemDriveString; NTSTATUS status; // Status UNICODE_STRING imgname; // ImageName UNICODE_STRING imgpath; // Nt ImagePath UNICODE_STRING dllpath; // Nt DllPath (DOS Name) UNICODE_STRING cmdline; // Nt CommandLine PRTL_USER_PROCESS_PARAMETERS processparameters; // ProcessParameters RTL_USER_PROCESS_INFORMATION processinformation={0}; // ProcessInformation WCHAR Env[2] = { 0,0 }; // Process Envirnoment PKUSER_SHARED_DATA SharedData = (PKUSER_SHARED_DATA)USER_SHARED_DATA; // Kernel Shared Data *hProcess = NULL; RtlDosPathNameToNtPathName_U(file_name, &nt_file, &file_part, NULL); RtlInitUnicodeString(&imgpath, nt_file.Buffer); // Image path RtlInitUnicodeString(&imgname, file_part); // Image name RtlInitUnicodeString(&dllpath, SharedData->NtSystemRoot); // DLL Path is %SystemRoot% RtlInitUnicodeString(&cmdline, cmd_line); // Command Line parameters status = RtlCreateProcessParameters(&processparameters, &imgname, &dllpath, &dllpath, &cmdline, Env, 0, 0, 0, 0); if (!NT_SUCCESS(status)) { RtlCliDisplayString("RtlCreateProcessParameters failed\n"); return STATUS_UNSUCCESSFUL; } DbgPrint("Launching Process: %s, DllPath=%s, CmdLine=%s", &imgname, &dllpath, &cmdline); status = RtlCreateUserProcess(&imgpath, OBJ_CASE_INSENSITIVE, processparameters, NULL, NULL, NULL, FALSE, NULL, NULL, &processinformation); if (!NT_SUCCESS(status)) { RtlCliDisplayString("RtlCreateUserProcess failed\n"); return STATUS_UNSUCCESSFUL; } status = NtResumeThread(processinformation.ThreadHandle, NULL); if (!NT_SUCCESS(status)) { RtlCliDisplayString("NtResumeThread failed\n"); return STATUS_UNSUCCESSFUL; } *hProcess = processinformation.ProcessHandle; return STATUS_SUCCESS; }
NTSTATUS NTAPI SmpExecuteImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, IN ULONG Flags, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation) { PRTL_USER_PROCESS_INFORMATION ProcessInfo; NTSTATUS Status; RTL_USER_PROCESS_INFORMATION LocalProcessInfo; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; /* Use the input process information if we have it, otherwise use local */ ProcessInfo = ProcessInformation; if (!ProcessInfo) ProcessInfo = &LocalProcessInfo; /* Create parameters for the target process */ Status = RtlCreateProcessParameters(&ProcessParameters, FileName, SmpDefaultLibPath.Length ? &SmpDefaultLibPath : NULL, Directory, CommandLine, SmpDefaultEnvironment, NULL, NULL, NULL, 0); if (!NT_SUCCESS(Status)) { /* This is a pretty bad failure. ASSERT on checked builds and exit */ ASSERTMSG("RtlCreateProcessParameters", NT_SUCCESS(Status)); DPRINT1("SMSS: RtlCreateProcessParameters failed for %wZ - Status == %lx\n", FileName, Status); return Status; } /* Set the size field as required */ ProcessInfo->Size = sizeof(RTL_USER_PROCESS_INFORMATION); /* Check if the debug flag was requested */ if (Flags & SMP_DEBUG_FLAG) { /* Write it in the process parameters */ ProcessParameters->DebugFlags = 1; } else { /* Otherwise inherit the flag that was passed to SMSS itself */ ProcessParameters->DebugFlags = SmpDebug; } /* Subsystems get the first 1MB of memory reserved for DOS/IVT purposes */ if (Flags & SMP_SUBSYSTEM_FLAG) { ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; } /* And always force NX for anything that SMSS launches */ ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_NX; /* Now create the process */ Status = RtlCreateUserProcess(FileName, OBJ_CASE_INSENSITIVE, ProcessParameters, NULL, NULL, NULL, FALSE, NULL, NULL, ProcessInfo); RtlDestroyProcessParameters(ProcessParameters); if (!NT_SUCCESS(Status)) { /* If we couldn't create it, fail back to the caller */ DPRINT1("SMSS: Failed load of %wZ - Status == %lx\n", FileName, Status); return Status; } /* Associate a session with this process */ Status = SmpSetProcessMuSessionId(ProcessInfo->ProcessHandle, MuSessionId); /* If the application is deferred (suspended), there's nothing to do */ if (Flags & SMP_DEFERRED_FLAG) return Status; /* Otherwise, get ready to start it, but make sure it's a native app */ if (ProcessInfo->ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE) { /* Resume it */ NtResumeThread(ProcessInfo->ThreadHandle, NULL); if (!(Flags & SMP_ASYNC_FLAG)) { /* Block on it unless Async was requested */ NtWaitForSingleObject(ProcessInfo->ThreadHandle, FALSE, NULL); } /* It's up and running now, close our handles */ NtClose(ProcessInfo->ThreadHandle); NtClose(ProcessInfo->ProcessHandle); } else { /* This image is invalid, so kill it, close our handles, and fail */ Status = STATUS_INVALID_IMAGE_FORMAT; NtTerminateProcess(ProcessInfo->ProcessHandle, Status); NtWaitForSingleObject(ProcessInfo->ThreadHandle, 0, 0); NtClose(ProcessInfo->ThreadHandle); NtClose(ProcessInfo->ProcessHandle); DPRINT1("SMSS: Not an NT image - %wZ\n", FileName); } /* Return the outcome of the process create */ return Status; }
/********************************************************************** * SmCreateUserProcess/5 * * DESCRIPTION * * ARGUMENTS * ImagePath: absolute path of the image to run; * CommandLine: arguments and options for ImagePath; * Flags: Wait flag: Set for boot time processes and unset for * subsystems bootstrapping; * 1Mb reserve flag: Set for subsystems, unset for everything * else * Timeout: optional: used if WaitForIt==TRUE; * ProcessHandle: optional: a duplicated handle for the child process (storage provided by the caller). * * RETURN VALUE * NTSTATUS: * */ NTSTATUS NTAPI SmCreateUserProcess (LPWSTR ImagePath, LPWSTR CommandLine, ULONG Flags, PLARGE_INTEGER Timeout OPTIONAL, PRTL_USER_PROCESS_INFORMATION UserProcessInfo OPTIONAL) { UNICODE_STRING ImagePathString = { 0, 0, NULL }; UNICODE_STRING CommandLineString = { 0, 0, NULL }; UNICODE_STRING SystemDirectory = { 0, 0, NULL }; PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; RTL_USER_PROCESS_INFORMATION ProcessInfo = {0}; PRTL_USER_PROCESS_INFORMATION pProcessInfo = & ProcessInfo; NTSTATUS Status = STATUS_SUCCESS; DPRINT("SM: %s called\n", __FUNCTION__); if (NULL != UserProcessInfo) { pProcessInfo = UserProcessInfo; } RtlInitUnicodeString (& ImagePathString, ImagePath); RtlInitUnicodeString (& CommandLineString, CommandLine); SystemDirectory.MaximumLength = (wcslen(SharedUserData->NtSystemRoot) * sizeof(WCHAR)) + sizeof(szSystemDirectory); SystemDirectory.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, SystemDirectory.MaximumLength); if (SystemDirectory.Buffer == NULL) { Status = STATUS_NO_MEMORY; DPRINT1("SM: %s: Allocating system directory string failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } Status = RtlAppendUnicodeToString(& SystemDirectory, SharedUserData->NtSystemRoot); if (!NT_SUCCESS(Status)) { goto FailProcParams; } Status = RtlAppendUnicodeToString(& SystemDirectory, szSystemDirectory); if (!NT_SUCCESS(Status)) { goto FailProcParams; } Status = RtlCreateProcessParameters(& ProcessParameters, & ImagePathString, NULL, & SystemDirectory, & CommandLineString, SmSystemEnvironment, NULL, NULL, NULL, NULL); RtlFreeHeap(RtlGetProcessHeap(), 0, SystemDirectory.Buffer); if (!NT_SUCCESS(Status)) { FailProcParams: DPRINT1("SM: %s: Creating process parameters failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Reserve lower 1Mb, if requested */ if (Flags & SM_CREATE_FLAG_RESERVE_1MB) ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; /* Create the user process */ Status = RtlCreateUserProcess (& ImagePathString, OBJ_CASE_INSENSITIVE, ProcessParameters, NULL, NULL, NULL, FALSE, NULL, NULL, pProcessInfo); RtlDestroyProcessParameters (ProcessParameters); if (!NT_SUCCESS(Status)) { DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n", __FUNCTION__, ImagePathString.Buffer, Status); return Status; } /* * It the caller is *not* interested in the child info, * resume it immediately. */ if (NULL == UserProcessInfo) { Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL); if(!NT_SUCCESS(Status)) { DPRINT1("SM: %s: NtResumeThread failed (Status=0x%08lx)\n", __FUNCTION__, Status); } } /* Wait for process termination */ if (Flags & SM_CREATE_FLAG_WAIT) { Status = NtWaitForSingleObject (pProcessInfo->ProcessHandle, FALSE, Timeout); if (!NT_SUCCESS(Status)) { DPRINT1("SM: %s: NtWaitForSingleObject failed with Status=0x%08lx\n", __FUNCTION__, Status); } } if (NULL == UserProcessInfo) { NtClose(pProcessInfo->ProcessHandle); NtClose(pProcessInfo->ThreadHandle); } return Status; }
NTSTATUS Nt_CreateProcess( LPCWSTR ApplicationName, LPWSTR CommandLine, ULONG CreationFlags, LPCWSTR CurrentDirectory, LPSTARTUPINFO StartupInfo, LPPROCESS_INFORMATION ProcessInformation ) { NTSTATUS Status; WCHAR FullPathBuffer[MAX_PATH *2], DllPathBuffer[0x3000]; UNICODE_STRING PathVariableName, DllPath, ImagePathName; UNICODE_STRING _CommandLine, _CurrentDirectory; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; RTL_USER_PROCESS_INFORMATION ProcessInfo; if (!RtlDosPathNameToNtPathName_U(ApplicationName, &ImagePathName, NULL, NULL)) return STATUS_OBJECT_PATH_NOT_FOUND; RTL_CONST_STRING(PathVariableName, L"Path"); DllPath.Length = 0; DllPath.MaximumLength = sizeof(DllPathBuffer); DllPath.Buffer = DllPathBuffer; RtlQueryEnvironmentVariable_U(NULL, &PathVariableName, &DllPath); if (CommandLine != NULL) RtlInitUnicodeString(&_CommandLine, CommandLine); if (CurrentDirectory != NULL) RtlInitUnicodeString(&_CurrentDirectory, CurrentDirectory); Status = RtlCreateProcessParameters( &ProcessParameters, &ImagePathName, &DllPath, CurrentDirectory == NULL ? NULL : &_CurrentDirectory, CommandLine == NULL ? NULL : &_CommandLine, NULL, NULL, NULL, NULL, NULL ); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&ImagePathName); return Status; } ProcessInfo.Size = sizeof(ProcessInfo); Status = RtlCreateUserProcess( &ImagePathName, OBJ_CASE_INSENSITIVE, ProcessParameters, NULL, NULL, NULL, FALSE, NULL, NULL, &ProcessInfo ); RtlDestroyProcessParameters(ProcessParameters); RtlFreeUnicodeString(&ImagePathName); if (!NT_SUCCESS(Status)) return Status; if (!FLAG_ON(CreationFlags, CREATE_SUSPENDED)) { NtResumeThread(ProcessInfo.ThreadHandle, NULL); } if (ProcessInformation == NULL) { NtClose(ProcessInfo.ProcessHandle); NtClose(ProcessInfo.ThreadHandle); return Status; } ProcessInformation->dwProcessId = (ULONG)ProcessInfo.ClientId.UniqueProcess; ProcessInformation->dwThreadId = (ULONG)ProcessInfo.ClientId.UniqueThread; ProcessInformation->hProcess = ProcessInfo.ProcessHandle; ProcessInformation->hThread = ProcessInfo.ThreadHandle; return Status; }