1 #define UNICODE
2 #define _UNICODE
3 
4 #define ANONYMOUSUNIONS
5 #include <windows.h>
6 #include <stdlib.h>
7 
8 #define NTOS_MODE_USER
9 #include <ndk/ntndk.h>
10 
11 
12 #define INCLUDE_THE_DDK_HEADERS
13 #ifdef INCLUDE_THE_DDK_HEADERS
14 #include <ddk/ntddk.h>
15 #define ROS_ACE_HEADER ACE_HEADER
16 #define ROS_ACE ACE
17 
18 #else
19 typedef LONG NTSTATUS, *PNTSTATUS;
20 
21 typedef struct _UNICODE_STRING
22 {
23    USHORT Length;
24    USHORT MaximumLength;
25    PWSTR Buffer;
26 } UNICODE_STRING, *PUNICODE_STRING;
27 
28 typedef struct _OBJECT_ATTRIBUTES {
29     ULONG Length;
30     HANDLE RootDirectory;
31     PUNICODE_STRING ObjectName;
32     ULONG Attributes;
33     PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR
34     PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE
35 } OBJECT_ATTRIBUTES;
36 typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
37 
38 typedef struct _ROS_ACE_HEADER
39 {
40   CHAR AceType;
41   CHAR AceFlags;
42   USHORT AceSize;
43 } ROS_ACE_HEADER, *PROS_ACE_HEADER;
44 
45 typedef struct
46 {
47   ACE_HEADER Header;
48   ACCESS_MASK AccessMask;
49 } ROS_ACE, *PROS_ACE;
50 
51 NTSYSAPI
52 NTSTATUS
53 NTAPI
54 RtlConvertSidToUnicodeString (
55 	IN OUT	PUNICODE_STRING	String,
56 	IN	PSID		Sid,
57 	IN	BOOLEAN		AllocateString
58 	);
59 
60 NTSYSAPI
61 NTSTATUS
62 NTAPI
63 RtlCreateAcl(
64 	PACL Acl,
65 	ULONG AclSize,
66 	ULONG AclRevision);
67 
68 NTSYSAPI
69 NTSTATUS
70 NTAPI
71 RtlAddAccessAllowedAce (
72 	PACL		Acl,
73 	ULONG		Revision,
74 	ACCESS_MASK	AccessMask,
75 	PSID		Sid
76 	);
77 
78 NTSYSAPI
79 NTSTATUS
80 NTAPI
81 RtlGetAce (
82 	PACL Acl,
83 	ULONG AceIndex,
84 	PROS_ACE *Ace
85 	);
86 
87 NTSYSAPI
88 NTSTATUS
89 NTAPI
90 ZwAllocateLocallyUniqueId(
91 	OUT PLUID Luid
92 	);
93 
94 NTSYSAPI
95 NTSTATUS
96 NTAPI
97 ZwCreateToken(
98 	OUT PHANDLE TokenHandle,
99 	IN ACCESS_MASK DesiredAccess,
100 	IN POBJECT_ATTRIBUTES ObjectAttributes,
101 	IN TOKEN_TYPE TokenType,
102 	IN PLUID AuthenticationId,
103 	IN PLARGE_INTEGER ExpirationTime,
104 	IN PTOKEN_USER TokenUser,
105 	IN PTOKEN_GROUPS TokenGroups,
106 	IN PTOKEN_PRIVILEGES TokenPrivileges,
107 	IN PTOKEN_OWNER TokenOwner,
108 	IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup,
109 	IN PTOKEN_DEFAULT_DACL TokenDefaultDacl,
110 	IN PTOKEN_SOURCE TokenSource
111 	);
112 #define NT_SUCCESS(StatCode)  ((NTSTATUS)(StatCode) >= 0)
113 #endif
114 
115 #include <stdio.h>
116 
117 #define INITIAL_PRIV_ENABLED SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED
118 #define INITIAL_PRIV_DISABLED 0
119 LUID_AND_ATTRIBUTES InitialPrivilegeSet[] =
120 {
121 	{ { 0x00000007, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeTcbPrivilege
122 	{ { 0x00000002, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeCreateTokenPrivilege
123 	{ { 0x00000009, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeTakeOwnershipPrivilege
124 	{ { 0x0000000f, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeCreatePagefilePrivilege
125 	{ { 0x00000004, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeLockMemoryPrivilege
126 	{ { 0x00000003, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeAssignPrimaryTokenPrivilege
127 	{ { 0x00000005, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeIncreaseQuotaPrivilege
128 	{ { 0x0000000e, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeIncreaseBasePriorityPrivilege
129 	{ { 0x00000010, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeCreatePermanentPrivilege
130 	{ { 0x00000014, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeDebugPrivilege
131 	{ { 0x00000015, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeAuditPrivilege
132 	{ { 0x00000008, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeSecurityPrivilege
133 	{ { 0x00000016, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeSystemEnvironmentPrivilege
134 	{ { 0x00000017, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeChangeNotifyPrivilege
135 	{ { 0x00000011, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeBackupPrivilege
136 	{ { 0x00000012, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeRestorePrivilege
137 	{ { 0x00000013, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeShutdownPrivilege
138 	{ { 0x0000000a, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeLoadDriverPrivilege
139 	{ { 0x0000000d, 0x00000000 }, INITIAL_PRIV_ENABLED  },	// SeProfileSingleProcessPrivilege
140 	{ { 0x0000000c, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeSystemtimePrivilege
141 	{ { 0x00000019, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeUndockPrivilege
142 	{ { 0x0000001c, 0x00000000 }, INITIAL_PRIV_DISABLED },	// SeManageVolumePrivilege
143 };
144 
145 typedef struct _SID_2
146 {
147 	UCHAR  Revision;
148 	UCHAR  SubAuthorityCount;
149 	SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
150 	ULONG SubAuthority[2];
151 } SID_2;
152 
153 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
154 void
155 PrintSid(SID_AND_ATTRIBUTES* pSid, TOKEN_OWNER* pOwner, TOKEN_PRIMARY_GROUP* pPrimary)
156 {
157 	UNICODE_STRING scSid;
158 
159 	RtlConvertSidToUnicodeString(&scSid, pSid->Sid, TRUE);
160 	printf("%wZ [", &scSid);
161 	LocalFree(scSid.Buffer);
162 
163 	if ( EqualSid(pSid->Sid, pOwner->Owner) )
164 		printf("owner,");
165 
166 	if ( EqualSid(pSid->Sid, pPrimary->PrimaryGroup) )
167 		printf("primary,");
168 
169 	if ( pSid->Attributes & SE_GROUP_ENABLED )
170 	{
171 		if ( pSid->Attributes & SE_GROUP_ENABLED_BY_DEFAULT )
172 			printf("enabled-default,");
173 		else
174 			printf("enabled,");
175 	}
176 
177 	if ( pSid->Attributes & SE_GROUP_LOGON_ID )
178 		printf("logon,");
179 
180 
181 	if ( pSid->Attributes & SE_GROUP_MANDATORY )
182 		printf("mandatory,");
183 
184 	printf("]\n");
185 }
186 
187 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188 void
189 DisplayTokenSids(TOKEN_USER* pUser,
190 				 TOKEN_GROUPS* pGroups,
191 				 TOKEN_OWNER* pOwner,
192 				 TOKEN_PRIMARY_GROUP* pPrimary)
193 {
194 	DWORD i;
195 
196 	printf("\nSids:\n");
197 	PrintSid(&pUser->User, pOwner, pPrimary);
198 	printf("\nGroups:\n");
199 	for (i = 0; i < pGroups->GroupCount; i++)
200 		PrintSid(&pGroups->Groups[i], pOwner, pPrimary);
201 }
202 
203 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204 void
205 DisplayTokenPrivileges(TOKEN_PRIVILEGES* pPriv)
206 {
207 	WCHAR buffer[256];
208 	DWORD i;
209 
210 	printf("\nprivileges:\n");
211 	for (i = 0; i < pPriv->PrivilegeCount; i++)
212 	{
213 		DWORD cbName = sizeof(buffer) / sizeof(buffer[0]);
214 		LookupPrivilegeName(0, &pPriv->Privileges[i].Luid, buffer, &cbName);
215 
216 		printf("%S{0x%08x, 0x%08x} [", buffer, pPriv->Privileges[i].Luid.HighPart, pPriv->Privileges[i].Luid.LowPart);
217 
218 		if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED )
219 			printf("enabled,");
220 		if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT )
221 			printf("default,");
222 		if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_USED_FOR_ACCESS )
223 			printf("used");
224 
225 		printf("]\n");
226 	}
227 }
228 
229 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
230 void
231 DisplayDacl(PACL pAcl)
232 {
233 	DWORD i;
234 	NTSTATUS status;
235 
236 	if ( ! pAcl )
237 	{
238 		printf("\nNo Default Dacl.\n");
239 		return;
240 	}
241 
242 	printf("\nDacl:\n");
243 	for (i = 0; i < pAcl->AceCount; i++)
244 	{
245 		UNICODE_STRING scSid;
246 		ROS_ACE* pAce;
247 		LPWSTR wszType = 0;
248 		PSID pSid;
249 
250 		status = RtlGetAce(pAcl, i, (ROS_ACE**) &pAce);
251 		if ( ! NT_SUCCESS(status) )
252 		{
253 			printf("RtlGetAce(): status = 0x%08x\n", status);
254 			break;
255 		}
256 
257 		pSid = (PSID) (pAce + 1);
258 		if ( pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE )
259 			wszType = L"allow";
260 		if ( pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE )
261 			wszType = L"deny ";
262 
263 		status = RtlConvertSidToUnicodeString(&scSid, pSid, TRUE);
264 		if ( ! NT_SUCCESS(status) )
265 		{
266 			printf("RtlConvertSidToUnicodeString(): status = 0x%08x\n", status);
267 			break;
268 		}
269 
270 		printf("%d.) %S %wZ 0x%08x\n", i, wszType, &scSid, pAce->AccessMask);
271 		LocalFree(scSid.Buffer);
272 	}
273 }
274 
275 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
276 PVOID
277 GetFromToken(HANDLE hToken, TOKEN_INFORMATION_CLASS tic)
278 {
279 	BOOL bResult;
280     DWORD n;
281 	PBYTE p = 0;
282 
283     bResult = GetTokenInformation(hToken, tic, 0, 0, &n);
284     if ( ! bResult && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
285 		return 0;
286 
287     p = (PBYTE) malloc(n);
288     if ( ! GetTokenInformation(hToken, tic, p, n, &n) )
289 	{
290 		printf("GetFromToken() failed for TOKEN_INFORMATION_CLASS(%d): %d\n", tic, GetLastError());
291 		free(p);
292 		return 0;
293 	}
294 
295 	return p;
296 }
297 
298 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299 void
300 DisplayToken(HANDLE hTokenSource)
301 {
302 	TOKEN_USER*			 pTokenUser         = (PTOKEN_USER)			 GetFromToken(hTokenSource, TokenUser);
303 	TOKEN_GROUPS*		 pTokenGroups		= (PTOKEN_GROUPS)		 GetFromToken(hTokenSource, TokenGroups);
304 	TOKEN_OWNER*		 pTokenOwner		= (PTOKEN_OWNER)		 GetFromToken(hTokenSource, TokenOwner);
305 	TOKEN_PRIMARY_GROUP* pTokenPrimaryGroup = (PTOKEN_PRIMARY_GROUP) GetFromToken(hTokenSource, TokenPrimaryGroup);
306 	TOKEN_PRIVILEGES*	 pTokenPrivileges	= (PTOKEN_PRIVILEGES)	 GetFromToken(hTokenSource, TokenPrivileges);
307 	TOKEN_DEFAULT_DACL*	 pTokenDefaultDacl	= (PTOKEN_DEFAULT_DACL)	 GetFromToken(hTokenSource, TokenDefaultDacl);
308 
309 	DisplayTokenSids(pTokenUser, pTokenGroups, pTokenOwner, pTokenPrimaryGroup);
310 	// DisplayTokenPrivileges(pTokenPrivileges);
311 	DisplayDacl(pTokenDefaultDacl->DefaultDacl);
312 
313 	free(pTokenUser);
314 	free(pTokenGroups);
315 	free(pTokenOwner);
316 	free(pTokenPrimaryGroup);
317 	free(pTokenPrivileges);
318 	free(pTokenDefaultDacl);
319 }
320 
321 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
322 BOOL
323 EnablePrivilege(LPWSTR wszName)
324 {
325     HANDLE hToken;
326     TOKEN_PRIVILEGES priv = {1, {{{0, 0}, SE_PRIVILEGE_ENABLED}}};
327 	BOOL bResult;
328 
329     LookupPrivilegeValue(0, wszName, &priv.Privileges[0].Luid);
330 
331     OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
332 
333     AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0);
334     bResult = GetLastError() == ERROR_SUCCESS;
335 
336     CloseHandle(hToken);
337     return bResult;
338 }
339 
340 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
341 NTSTATUS
342 CreateInitialSystemToken(HANDLE* phSystemToken)
343 {
344 	static SID   sidSystem			  = { 1, 1, {SECURITY_NT_AUTHORITY}, {SECURITY_LOCAL_SYSTEM_RID} };
345 	static SID   sidEveryone		  = { 1, 1, {SECURITY_WORLD_SID_AUTHORITY}, {SECURITY_WORLD_RID} };
346 	static SID   sidAuthenticatedUser = { 1, 1, {SECURITY_NT_AUTHORITY}, {SECURITY_AUTHENTICATED_USER_RID} };
347 	static SID_2 sidAdministrators	  = { 1, 2, {SECURITY_NT_AUTHORITY}, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS} };
348 	static const int nGroupCount = 3;
349 
350 	NTSTATUS status;
351 	ULONG uSize;
352 	DWORD i;
353 
354 	TOKEN_USER			tkUser;
355 	TOKEN_OWNER			tkDefaultOwner;
356 	TOKEN_PRIMARY_GROUP	tkPrimaryGroup;
357 
358 	TOKEN_GROUPS*		ptkGroups = 0;
359 	TOKEN_PRIVILEGES*	ptkPrivileges = 0;
360 	TOKEN_DEFAULT_DACL	tkDefaultDacl = { 0 };
361 
362 	LARGE_INTEGER tkExpiration;
363 
364 	LUID authId = SYSTEM_LUID;
365 
366 	TOKEN_SOURCE source =
367 	{
368 		{ '*', '*', 'A', 'N', 'O', 'N', '*', '*' },
369 		{0, 0}
370 	};
371 
372 	SECURITY_QUALITY_OF_SERVICE sqos =
373 	{
374 		sizeof(sqos),
375 		SecurityAnonymous,
376 		SECURITY_STATIC_TRACKING,
377 		FALSE
378 	};
379 
380 	OBJECT_ATTRIBUTES oa =
381 	{
382 		sizeof(oa),
383 		0,
384 		0,
385 		0,
386 		0,
387 		&sqos
388 	};
389 
390 	tkExpiration.QuadPart = -1;
391 	status = ZwAllocateLocallyUniqueId(&source.SourceIdentifier);
392 	if ( status != 0 )
393 		return status;
394 
395 	tkUser.User.Sid = &sidSystem;
396 	tkUser.User.Attributes = 0;
397 
398 	// Under WinXP (the only MS OS I've tested) ZwCreateToken()
399 	// squawks if we use sidAdministrators here -- though running
400 	// a progrem under AT and using the DisplayToken() function
401 	// shows that the system token does default ownership to
402 	// Administrator.
403 
404 	// For now, default ownership to system, since that works
405 	tkDefaultOwner.Owner = &sidSystem;
406 	tkPrimaryGroup.PrimaryGroup = &sidSystem;
407 
408 	uSize = sizeof(TOKEN_GROUPS) - sizeof(ptkGroups->Groups);
409 	uSize += sizeof(SID_AND_ATTRIBUTES) * nGroupCount;
410 
411 	ptkGroups = (TOKEN_GROUPS*) malloc(uSize);
412 	ptkGroups->GroupCount = nGroupCount;
413 
414 	ptkGroups->Groups[0].Sid = (SID*) &sidAdministrators;
415 	ptkGroups->Groups[0].Attributes = SE_GROUP_ENABLED;
416 
417 	ptkGroups->Groups[1].Sid = &sidEveryone;
418 	ptkGroups->Groups[1].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
419 
420 	ptkGroups->Groups[2].Sid = &sidAuthenticatedUser;
421 	ptkGroups->Groups[2].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
422 
423 	uSize = sizeof(TOKEN_PRIVILEGES) - sizeof(ptkPrivileges->Privileges);
424 	uSize += sizeof(LUID_AND_ATTRIBUTES) * sizeof(InitialPrivilegeSet) / sizeof(InitialPrivilegeSet[0]);
425 	ptkPrivileges = (TOKEN_PRIVILEGES*) malloc(uSize);
426 	ptkPrivileges->PrivilegeCount = sizeof(InitialPrivilegeSet) / sizeof(InitialPrivilegeSet[0]);
427 	for (i = 0; i < ptkPrivileges->PrivilegeCount; i++)
428 	{
429 		ptkPrivileges->Privileges[i].Luid.HighPart = InitialPrivilegeSet[i].Luid.HighPart;
430 		ptkPrivileges->Privileges[i].Luid.LowPart = InitialPrivilegeSet[i].Luid.LowPart;
431 		ptkPrivileges->Privileges[i].Attributes = InitialPrivilegeSet[i].Attributes;
432 	}
433 
434 	// Calculate the length needed for the ACL
435 	uSize = sizeof(ACL);
436 	uSize += sizeof(ACE) + sizeof(sidSystem);
437 	uSize += sizeof(ACE) + sizeof(sidAdministrators);
438 	uSize = (uSize & (~3)) + 8;
439 	tkDefaultDacl.DefaultDacl = (PACL) malloc(uSize);
440 
441 	status = RtlCreateAcl(tkDefaultDacl.DefaultDacl, uSize, ACL_REVISION);
442 	if ( ! NT_SUCCESS(status) )
443 		printf("RtlCreateAcl() failed: 0x%08x\n", status);
444 
445 	status = RtlAddAccessAllowedAce(tkDefaultDacl.DefaultDacl, ACL_REVISION, GENERIC_ALL, &sidSystem);
446 	if ( ! NT_SUCCESS(status) )
447 		printf("RtlAddAccessAllowedAce() failed: 0x%08x\n", status);
448 
449 	status = RtlAddAccessAllowedAce(tkDefaultDacl.DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_EXECUTE|READ_CONTROL, (PSID) &sidAdministrators);
450 	if ( ! NT_SUCCESS(status) )
451 		printf("RtlAddAccessAllowedAce() failed: 0x%08x\n", status);
452 
453 	printf("Parameters being passed into ZwCreateToken:\n\n");
454 	DisplayTokenSids(&tkUser, ptkGroups, &tkDefaultOwner, &tkPrimaryGroup);
455 	DisplayDacl(tkDefaultDacl.DefaultDacl);
456 
457 	printf("Calling ZwCreateToken()...\n");
458 	status = ZwCreateToken(phSystemToken,
459 						   TOKEN_ALL_ACCESS,
460 						   &oa,
461 						   TokenPrimary,
462 						   &authId,
463 						   &tkExpiration,
464 						   &tkUser,
465 						   ptkGroups,
466 						   ptkPrivileges,
467 						   &tkDefaultOwner,
468 						   &tkPrimaryGroup,
469 						   &tkDefaultDacl,
470 						   &source);
471 
472 	// Cleanup
473 	free(ptkGroups);
474 	free(ptkPrivileges);
475 	free(tkDefaultDacl.DefaultDacl);
476 
477 	return status;
478 }
479 
480 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
481 int
482 main(int argc, char* argv[])
483 {
484 	NTSTATUS Status;
485 	HANDLE hSystemToken;
486 	CHAR buffer[512];
487 	HANDLE hOurToken;
488 
489         printf("Current process Token:\n");
490 
491         Status=ZwOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_QUERY_SOURCE, &hOurToken);
492 	if ( NT_SUCCESS(Status) )
493 	{
494 	  DisplayToken(hOurToken);
495 	  CloseHandle(hOurToken);
496 	}
497 	else
498 	{
499 	  printf("ZwOpenProcessToken() failed: 0x%08x\n", Status);
500 	}
501 
502 //#define ENABLE_PRIVILEGE
503 #ifdef ENABLE_PRIVILEGE
504     EnablePrivilege(SE_CREATE_TOKEN_NAME);
505 #endif
506 
507 	// Now do the other one
508 	Status = CreateInitialSystemToken(&hSystemToken);
509 	if ( NT_SUCCESS(Status) )
510 	{
511 		printf("System Token: 0x%08x\n", hSystemToken);
512 		DisplayToken(hSystemToken);
513 		CloseHandle(hSystemToken);
514 	}
515 	else
516 	{
517 		printf("CreateInitialSystemToken() return: 0x%08x\n", Status);
518 	}
519 
520 	printf("press return");
521 	gets(buffer);
522 
523 	return 0;
524 }
525