aboutsummaryrefslogtreecommitdiff
path: root/SMSSBSOD/Main.c
blob: 8404e24b0a4375de47591b0dd4dbda750039a2fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * 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 <stdio.h>
#include <Windows.h>
#include <winternl.h>
#include <stdlib.h>

#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;
}