/* * Adopted from http://www.rohitab.com/discuss/topic/41379-running-native-applications-with-rtlcreateuserprocess/ * * Running smss.exe on my 21H2 (OS Build 19044.2006) will crash the kernel with 0x000021a. * */ #include #include #include #include #pragma comment(lib,"ntdll.lib") typedef struct _SECTION_IMAGE_INFORMATION { PVOID TransferAddress; ULONG ZeroBits; SIZE_T MaximumStackSize; SIZE_T CommittedStackSize; ULONG SubSystemType; union { struct { USHORT SubSystemMinorVersion; USHORT SubSystemMajorVersion; }; ULONG SubSystemVersion; }; ULONG GpValue; USHORT ImageCharacteristics; USHORT DllCharacteristics; USHORT Machine; BOOLEAN ImageContainsCode; BOOLEAN Spare1; ULONG LoaderFlags; ULONG ImageFileSize; ULONG Reserved[1]; } SECTION_IMAGE_INFORMATION, * PSECTION_IMAGE_INFORMATION; typedef struct _RTL_USER_PROCESS_INFORMATION { ULONG Size; HANDLE ProcessHandle; HANDLE ThreadHandle; CLIENT_ID ClientId; SECTION_IMAGE_INFORMATION ImageInformation; } RTL_USER_PROCESS_INFORMATION, * PRTL_USER_PROCESS_INFORMATION; static UNICODE_STRING FileName; static UNICODE_STRING CmdLine; static RTL_USER_PROCESS_INFORMATION ProcessInfo; static PRTL_USER_PROCESS_PARAMETERS UserProcessParam; static void cleanup(void) { RtlFreeUnicodeString(&FileName); RtlDestroyProcessParameters(UserProcessParam); NtClose(ProcessInfo.ThreadHandle); NtClose(ProcessInfo.ProcessHandle); } int wmain(int argc, wchar_t* argv[]) { atexit(cleanup); wchar_t Path[512], CmdLine[512]; NTSTATUS Result; if (argc < 2) { printf("Usage: ntstart.exe [Filename] [Command line]\n"); return -1; } if (!SearchPath(NULL, argv[1], L".exe", 512, Path, NULL)) { printf("Error: File not found\n"); return 1; } if (!RtlDosPathNameToNtPathName_U(Path, &FileName, NULL, NULL)) { printf("Error: Unable to convert path name\n"); return 1; } if (argc > 2) { swprintf(CmdLine, L"\"%ws\" %ws", Path, argv[2]); RtlInitUnicodeString(&CmdLine, CmdLine); } if (!NT_SUCCESS(Result = RtlCreateProcessParameters( &UserProcessParam, &FileName, NULL, NULL, argc > 2 ? &CmdLine : NULL, NULL, NULL, NULL, NULL, NULL))) { printf("Error: Unable to create process parameters: %x\n", Result); return Result; } if (!NT_SUCCESS(Result = RtlCreateUserProcess( &FileName, OBJ_CASE_INSENSITIVE, UserProcessParam, NULL, NULL, NULL, FALSE, NULL, NULL, &ProcessInfo))) { printf("Error: Unable to create process: %x\n", Result); return Result; } if (!NT_SUCCESS(Result = NtResumeThread(ProcessInfo.ThreadHandle, NULL))) { printf("Error: Unable to start process: %x\n", Result); return Result; } if (!NT_SUCCESS(Result = NtWaitForSingleObject(ProcessInfo.ProcessHandle, FALSE, NULL))) { printf("Error: Unable to wait for process: %x\n", Result); return Result; } printf("Process exited.\n"); return 0; }