00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
00016
NTSTATUS
00017 OpenEffectiveToken(
00018 PHANDLE phToken)
00019 {
00020
NTSTATUS Status;
00021
00022
00023
00024
00025
Status = ZwOpenThreadToken(
00026 NtCurrentThread(),
00027 TOKEN_QUERY,
00028 (BOOLEAN)
TRUE,
00029 phToken
00030 );
00031
if (
Status == STATUS_NO_TOKEN) {
00032
00033
00034
00035
00036
Status = ZwOpenProcessToken(
00037 NtCurrentProcess(),
00038 TOKEN_QUERY,
00039 phToken
00040 );
00041 }
00042
00043
if (!
NT_SUCCESS(
Status)) {
00044 RIPMSG1(RIP_WARNING,
"Can't open client's token! - Status = %lx",
Status);
00045 }
00046
return Status;
00047 }
00048
00049
NTSTATUS
00050 GetProcessLuid(
00051
PETHREAD Thread,
00052 PLUID LuidProcess
00053 )
00054 {
00055 PACCESS_TOKEN UserToken =
NULL;
00056 BOOLEAN fCopyOnOpen;
00057 BOOLEAN fEffectiveOnly;
00058 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
00059
NTSTATUS Status;
00060
00061
if (Thread ==
NULL)
00062 Thread =
PsGetCurrentThread();
00063
00064
00065
00066
00067
00068 UserToken =
PsReferenceImpersonationToken(Thread,
00069 &fCopyOnOpen, &fEffectiveOnly, &ImpersonationLevel);
00070
00071
if (UserToken ==
NULL) {
00072
00073
00074
00075
00076
00077 UserToken =
PsReferencePrimaryToken(Thread->
ThreadsProcess);
00078
if (UserToken ==
NULL)
00079
return STATUS_NO_TOKEN;
00080 }
00081
00082
Status =
SeQueryAuthenticationIdToken(UserToken, LuidProcess);
00083
00084
00085
00086
00087
00088
ObDereferenceObject(UserToken);
00089
00090
return Status;
00091 }
00092
00093
00094 BOOLEAN
00095 IsRestricted(
00096
PETHREAD Thread
00097 )
00098 {
00099 PACCESS_TOKEN UserToken;
00100 BOOLEAN fCopyOnOpen;
00101 BOOLEAN fEffectiveOnly;
00102 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
00103 BOOLEAN fRestricted =
FALSE;
00104
00105
00106
00107
00108 UserToken =
PsReferenceImpersonationToken(Thread,
00109 &fCopyOnOpen, &fEffectiveOnly, &ImpersonationLevel);
00110
00111
00112
00113
00114
if (UserToken ==
NULL) {
00115 UserToken =
PsReferencePrimaryToken(Thread->
ThreadsProcess);
00116 }
00117
00118
00119
00120
00121
if (UserToken !=
NULL) {
00122 fRestricted =
SeTokenIsRestricted(UserToken);
00123
ObDereferenceObject(UserToken);
00124 }
00125
00126
return fRestricted;
00127 }
00128
00129
00130
NTSTATUS
00131 CreateSystemThread(
00132 PKSTART_ROUTINE lpThreadAddress,
00133 PVOID pvContext,
00134 PHANDLE phThread)
00135 {
00136
NTSTATUS Status;
00137 OBJECT_ATTRIBUTES Obja;
00138 HANDLE hProcess;
00139
00140
CheckCritOut();
00141
00142 InitializeObjectAttributes(&Obja,
00143
NULL,
00144 0,
00145
NULL,
00146
NULL);
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 UserAssert(
gpepCSRSS !=
NULL);
00159
00160
Status =
ObOpenObjectByPointer(
00161
gpepCSRSS,
00162 0,
00163
NULL,
00164 PROCESS_CREATE_THREAD,
00165
NULL,
00166
KernelMode,
00167 &hProcess);
00168
00169
if (!
NT_SUCCESS(
Status)) {
00170
return Status;
00171 }
00172
00173 UserAssert(hProcess !=
NULL);
00174
00175
Status =
PsCreateSystemThread(
00176 phThread,
00177 THREAD_ALL_ACCESS,
00178 &Obja,
00179 hProcess,
00180
NULL,
00181 lpThreadAddress,
00182 pvContext);
00183
00184 ZwClose(hProcess);
00185
00186
return Status;
00187 }
00188
00189
00190
NTSTATUS
00191 InitSystemThread(
00192 PUNICODE_STRING pstrThreadName)
00193 {
00194
PETHREAD pEThread;
00195
PEPROCESS Process;
00196
PTHREADINFO pti;
00197
NTSTATUS Status;
00198
00199
CheckCritOut();
00200
00201 pEThread =
PsGetCurrentThread();
00202 Process = pEThread->
ThreadsProcess;
00203
00204
ValidateThreadSessionId(pEThread);
00205
00206
00207
00208
00209
00210
if (Process->
Win32Process ==
NULL) {
00211
Status = W32pProcessCallout(Process,
TRUE);
00212
if (!
NT_SUCCESS(
Status)) {
00213
return Status;
00214 }
00215 }
00216
00217
00218
00219
00220
00221
Status = AllocateW32Thread(pEThread);
00222
if (!
NT_SUCCESS(
Status)) {
00223
return Status;
00224 }
00225
00226
EnterCrit();
00227
00228
00229
00230
00231
00232
00233
Status =
xxxCreateThreadInfo(pEThread,
TRUE);
00234
if (!
NT_SUCCESS(
Status)) {
00235 FreeW32Thread(pEThread);
00236
LeaveCrit();
00237
return Status;
00238 }
00239
00240 pti =
PtiCurrentShared();
00241
if (pstrThreadName) {
00242
if (pti->
pstrAppName !=
NULL)
00243 UserFreePool(pti->
pstrAppName);
00244 pti->
pstrAppName = UserAllocPoolWithQuota(
sizeof(UNICODE_STRING) +
00245 pstrThreadName->Length +
sizeof(WCHAR), TAG_TEXT);
00246
if (pti->
pstrAppName !=
NULL) {
00247 pti->
pstrAppName->Buffer = (PWCHAR)(pti->
pstrAppName + 1);
00248 RtlCopyMemory(pti->
pstrAppName->Buffer, pstrThreadName->Buffer,
00249 pstrThreadName->Length);
00250 pti->
pstrAppName->Buffer[pstrThreadName->Length /
sizeof(WCHAR)] = 0;
00251 pti->
pstrAppName->MaximumLength = pstrThreadName->Length +
sizeof(WCHAR);
00252 pti->
pstrAppName->Length = pstrThreadName->Length;
00253 }
00254 }
00255
00256
00257
00258
00259
00260
00261
if ((pti->
ppi !=
NULL) && (pti->
ppi->W32PF_Flags & W32PF_APPSTARTING)) {
00262
ClearAppStarting(pti->
ppi);
00263 }
00264
00265
LeaveCrit();
00266
00267
return STATUS_SUCCESS;
00268 }
00269
00270
VOID
00271 UserRtlRaiseStatus(
00272 NTSTATUS Status)
00273 {
00274
ExRaiseStatus(
Status);
00275 }
00276
00277
NTSTATUS
00278 CommitReadOnlyMemory(
00279 HANDLE hSection,
00280 PSIZE_T pCommitSize,
00281 DWORD dwCommitOffset,
00282
int* pdCommit)
00283 {
00284 SIZE_T ulViewSize;
00285 LARGE_INTEGER liOffset;
00286
PEPROCESS Process;
00287 PVOID pUserBase, pvt;
00288
NTSTATUS Status;
00289
00290 ulViewSize = 0;
00291 pUserBase =
NULL;
00292 liOffset.QuadPart = 0;
00293 Process =
PsGetCurrentProcess();
00294
00295
Status =
MmMapViewOfSection(
00296 hSection,
00297 Process,
00298 &pUserBase,
00299 0,
00300
PAGE_SIZE,
00301 &liOffset,
00302 &ulViewSize,
00303 ViewUnmap,
00304 SEC_NO_CHANGE,
00305 PAGE_EXECUTE_READ);
00306
00307
if (
NT_SUCCESS(
Status)) {
00308
00309
00310
00311
00312 pUserBase = pvt = (PVOID)((
PBYTE)pUserBase + dwCommitOffset);
00313
00314
Status = ZwAllocateVirtualMemory(
00315 NtCurrentProcess(),
00316 &pUserBase,
00317 0,
00318 pCommitSize,
00319 MEM_COMMIT,
00320 PAGE_EXECUTE_READ);
00321
00322
if (pdCommit) {
00323 *pdCommit = (
int)((
PBYTE)pUserBase - (
PBYTE)pvt);
00324 }
00325
#if DBG
00326
else {
00327 UserAssert(pvt == pUserBase);
00328 }
00329
#endif
00330
00331
MmUnmapViewOfSection(Process, pUserBase);
00332 }
00333
return Status;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 PKEVENT CreateKernelEvent(
00347 IN EVENT_TYPE Type,
00348 IN BOOLEAN State)
00349 {
00350
PKEVENT pEvent;
00351
00352 pEvent = UserAllocPoolNonPaged(
sizeof(
KEVENT), TAG_SYSTEM);
00353
if (pEvent !=
NULL) {
00354
KeInitializeEvent(pEvent, Type, State);
00355 }
00356
return pEvent;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 VOID LockObjectAssignment(
00369 PVOID *pplock,
00370 PVOID pobject
00371 #ifdef LOGDESKTOPLOCKS
00372 ,DWORD tag,
00373 ULONG_PTR extra
00374 #endif
00375 )
00376 {
00377 PVOID pobjectOld;
00378
00379
00380
00381
00382
00383
00384 pobjectOld = *pplock;
00385
00386
00387
00388
00389
if (pobject !=
NULL) {
00390
ObReferenceObject(pobject);
00391
#ifdef LOGDESKTOPLOCKS
00392
if (
OBJECT_TO_OBJECT_HEADER(pobject)->Type == *
ExDesktopObjectType) {
00393
LogDesktop(pobject, tag,
TRUE, extra);
00394 }
00395
#endif
00396
}
00397 *pplock = pobject;
00398
00399
00400
00401
00402
if (pobjectOld !=
NULL) {
00403
#ifdef LOGDESKTOPLOCKS
00404
if (
OBJECT_TO_OBJECT_HEADER(pobjectOld)->Type == *
ExDesktopObjectType) {
00405
LogDesktop(pobjectOld, tag,
FALSE, extra);
00406 }
00407
#endif
00408
ObDereferenceObject(pobjectOld);
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 VOID UnlockObjectAssignment(
00422 PVOID *pplock
00423 #ifdef LOGDESKTOPLOCKS
00424 ,DWORD tag,
00425 ULONG_PTR extra
00426 #endif
00427 )
00428 {
00429
if (*pplock !=
NULL) {
00430
#ifdef LOGDESKTOPLOCKS
00431
if (
OBJECT_TO_OBJECT_HEADER(*pplock)->Type == *
ExDesktopObjectType) {
00432
LogDesktop(*pplock, tag,
FALSE, extra);
00433 }
00434
#endif
00435
ObDereferenceObject(*pplock);
00436 *pplock =
NULL;
00437 }
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 VOID UserDereferenceObject(
00449 PVOID pobj)
00450 {
00451
ObDereferenceObject(pobj);
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 NTSTATUS ProtectHandle(
00465 IN HANDLE Handle,
00466 IN BOOLEAN Protect)
00467 {
00468 OBJECT_HANDLE_FLAG_INFORMATION HandleInfo;
00469
NTSTATUS Status;
00470
00471
Status = ZwQueryObject(
00472
Handle,
00473 ObjectHandleFlagInformation,
00474 &HandleInfo,
00475
sizeof(HandleInfo),
00476
NULL);
00477
if (
NT_SUCCESS(
Status)) {
00478 HandleInfo.ProtectFromClose = Protect;
00479
00480
Status = ZwSetInformationObject(
00481
Handle,
00482 ObjectHandleFlagInformation,
00483 &HandleInfo,
00484
sizeof(HandleInfo));
00485 }
00486
00487
return Status;
00488 }
00489
00490
#ifdef LOGDESKTOPLOCKS
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
#define LOG_DELTA 8
00501
00502 PLogD GrowLogIfNecessary(
00503
PDESKTOP pdesk)
00504 {
00505
if (pdesk->nLogCrt < pdesk->nLogMax) {
00506 UserAssert(pdesk->pLog != NULL);
00507
return pdesk->pLog;
00508 }
00509
00510
00511
00512
00513
if (pdesk->pLog ==
NULL) {
00514
00515 UserAssert(pdesk->nLogMax == 0 && pdesk->nLogCrt == 0);
00516
00517 pdesk->pLog = (PLogD)UserAllocPool(LOG_DELTA *
sizeof(LogD), TAG_LOGDESKTOP);
00518
00519 }
else {
00520 pdesk->pLog = (PLogD)UserReAllocPool(pdesk->pLog,
00521 pdesk->nLogCrt *
sizeof(LogD),
00522 (pdesk->nLogCrt + LOG_DELTA) *
sizeof(LogD),
00523 TAG_LOGDESKTOP);
00524 }
00525
00526 UserAssert(pdesk->pLog != NULL);
00527
00528 pdesk->nLogMax += LOG_DELTA;
00529
00530
return pdesk->pLog;
00531 }
00532
00533
00534
void LogDesktop(
00535
PDESKTOP pdesk,
00536 DWORD tag,
00537 BOOL bLock,
00538 ULONG_PTR extra)
00539 {
00540
DWORD tag1 = 0, tag2 = 0;
00541 PLogD pLog;
00542
00543
if (pdesk ==
NULL) {
00544
return;
00545 }
00546
00547
00548
00549
00550 UserAssert(HIWORD(tag) == 0);
00551
00552
if (bLock) {
00553
00554 ULONG hash;
00555
00556 (pdesk->nLockCount)++;
00557
00558 growAndAdd:
00559
00560
00561
00562
00563 pLog = GrowLogIfNecessary(pdesk);
00564
00565 pLog += pdesk->nLogCrt;
00566
00567 pLog->tag = (WORD)tag;
00568 pLog->type = (WORD)bLock;
00569 pLog->extra = extra;
00570
00571 RtlZeroMemory(pLog->trace, 6 *
sizeof(PVOID));
00572
00573 GetStackTrace(2,
00574 6,
00575 pLog->trace,
00576 &hash);
00577
00578 (pdesk->nLogCrt)++;
00579
return;
00580 }
00581
00582
00583
00584
00585
00586 UserAssert(pdesk->nLockCount > 0);
00587
00588
switch (tag) {
00589
case LDU_CLS_DESKPARENT1:
00590 tag1 = LDL_CLS_DESKPARENT1;
00591
break;
00592
case LDU_CLS_DESKPARENT2:
00593 tag1 = LDL_CLS_DESKPARENT1;
00594 tag2 = LDL_CLS_DESKPARENT2;
00595
break;
00596
case LDU_FN_DESTROYCLASS:
00597 tag1 = LDL_FN_DESTROYCLASS;
00598
break;
00599
case LDU_FN_DESTROYMENU:
00600 tag1 = LDL_FN_DESTROYMENU;
00601
break;
00602
case LDU_FN_DESTROYTHREADINFO:
00603 tag1 = LDL_FN_DESTROYTHREADINFO;
00604
break;
00605
case LDU_FN_DESTROYWINDOWSTATION:
00606 tag1 = LDL_FN_DESTROYWINDOWSTATION;
00607
break;
00608
case LDU_DESKDISCONNECT:
00609 tag1 = LDL_DESKDISCONNECT;
00610
break;
00611
case LDU_DESK_DESKNEXT:
00612 tag1 = LDL_DESK_DESKNEXT1;
00613
break;
00614
case LDU_OBJ_DESK:
00615 tag1 = LDL_OBJ_DESK;
00616 tag2 = LDL_MOTHERDESK_DESK1;
00617
break;
00618
case LDL_PTI_DESK:
00619 tag1 = LDL_PTI_DESK;
00620 tag2 = LDL_DT_DESK;
00621
break;
00622
case LDU_PTI_DESK:
00623 tag1 = LDL_PTI_DESK;
00624
break;
00625
case LDU_PPI_DESKSTARTUP1:
00626
case LDU_PPI_DESKSTARTUP2:
00627
case LDU_PPI_DESKSTARTUP3:
00628 tag1 = LDL_PPI_DESKSTARTUP1;
00629 tag2 = LDL_PPI_DESKSTARTUP2;
00630
break;
00631
case LDU_DESKLOGON:
00632 tag1 = LDL_DESKLOGON;
00633
break;
00634
00635
case LDUT_FN_FREEWINDOW:
00636 tag1 = LDLT_FN_FREEWINDOW;
00637
break;
00638
case LDUT_FN_DESKTOPTHREAD_DESK:
00639 tag1 = LDLT_FN_DESKTOPTHREAD_DESK;
00640
break;
00641
case LDUT_FN_DESKTOPTHREAD_DESKTEMP:
00642 tag1 = LDLT_FN_DESKTOPTHREAD_DESKTEMP;
00643
break;
00644
case LDUT_FN_SETDESKTOP:
00645 tag1 = LDLT_FN_SETDESKTOP;
00646
break;
00647
case LDUT_FN_NTUSERSWITCHDESKTOP:
00648 tag1 = LDLT_FN_NTUSERSWITCHDESKTOP;
00649
break;
00650
case LDUT_FN_SENDMESSAGEBSM1:
00651
case LDUT_FN_SENDMESSAGEBSM2:
00652 tag1 = LDLT_FN_SENDMESSAGEBSM;
00653
break;
00654
case LDUT_FN_SYSTEMBROADCASTMESSAGE:
00655 tag1 = LDLT_FN_SYSTEMBROADCASTMESSAGE;
00656
break;
00657
case LDUT_FN_CTXREDRAWSCREEN:
00658 tag1 = LDLT_FN_CTXREDRAWSCREEN;
00659
break;
00660
case LDUT_FN_CTXDISABLESCREEN:
00661 tag1 = LDLT_FN_CTXDISABLESCREEN;
00662
break;
00663
00664
case LD_DEREF_FN_CREATEDESKTOP1:
00665
case LD_DEREF_FN_CREATEDESKTOP2:
00666
case LD_DEREF_FN_CREATEDESKTOP3:
00667 tag1 = LD_REF_FN_CREATEDESKTOP;
00668
break;
00669
case LD_DEREF_FN_OPENDESKTOP:
00670 tag1 = LD_REF_FN_OPENDESKTOP;
00671
break;
00672
case LD_DEREF_FN_SETDESKTOP:
00673 tag1 = LD_REF_FN_SETDESKTOP;
00674
break;
00675
case LD_DEREF_FN_GETTHREADDESKTOP:
00676 tag1 = LD_REF_FN_GETTHREADDESKTOP;
00677
break;
00678
case LD_DEREF_FN_CLOSEDESKTOP1:
00679
case LD_DEREF_FN_CLOSEDESKTOP2:
00680 tag1 = LD_REF_FN_CLOSEDESKTOP;
00681
break;
00682
case LD_DEREF_FN_RESOLVEDESKTOP:
00683 tag1 = LD_REF_FN_RESOLVEDESKTOP;
00684
break;
00685
case LD_DEREF_VALIDATE_HDESK1:
00686
case LD_DEREF_VALIDATE_HDESK2:
00687
case LD_DEREF_VALIDATE_HDESK3:
00688
case LD_DEREF_VALIDATE_HDESK4:
00689 tag1 = LDL_VALIDATE_HDESK;
00690
break;
00691
case LDUT_FN_CREATETHREADINFO1:
00692
case LDUT_FN_CREATETHREADINFO2:
00693 tag1 = LDLT_FN_CREATETHREADINFO;
00694
break;
00695
case LD_DEREF_FN_SETCSRSSTHREADDESKTOP1:
00696
case LD_DEREF_FN_SETCSRSSTHREADDESKTOP2:
00697 tag1 = LD_REF_FN_SETCSRSSTHREADDESKTOP;
00698
break;
00699
case LD_DEREF_FN_CONSOLECONTROL1:
00700 tag1 = LD_REF_FN_CONSOLECONTROL1;
00701
break;
00702
case LD_DEREF_FN_CONSOLECONTROL2:
00703 tag1 = LD_REF_FN_CONSOLECONTROL2;
00704
break;
00705
case LD_DEREF_FN_GETUSEROBJECTINFORMATION:
00706 tag1 = LD_REF_FN_GETUSEROBJECTINFORMATION;
00707
break;
00708
case LD_DEREF_FN_SETUSEROBJECTINFORMATION:
00709 tag1 = LD_REF_FN_SETUSEROBJECTINFORMATION;
00710
break;
00711
case LD_DEREF_FN_CREATEWINDOWSTATION:
00712 tag1 = LD_REF_FN_CREATEWINDOWSTATION;
00713
break;
00714
00715
case LDL_TERM_DESKDESTROY1:
00716 tag1 = LDL_TERM_DESKDESTROY2;
00717
break;
00718
case LDL_MOTHERDESK_DESK1:
00719 tag1 = LDL_MOTHERDESK_DESK1;
00720 tag2 = LDL_MOTHERDESK_DESK2;
00721
break;
00722
case LDL_WINSTA_DESKLIST2:
00723 tag1 = LDL_WINSTA_DESKLIST1;
00724
break;
00725
case LDL_DESKRITINPUT:
00726
case LDU_DESKRITINPUT:
00727 tag1 = LDL_DESKRITINPUT;
00728
break;
00729 }
00730
00731
if (tag1 != 0) {
00732
00733
int ind;
00734
00735
00736
00737
00738
00739
00740
for (ind = pdesk->nLogCrt - 1; ind >= 0; ind--) {
00741 pLog = pdesk->pLog + ind;
00742
00743
if (pLog->type == 1 &&
00744 (pLog->tag == tag1 || pLog->tag == tag2) &&
00745 pLog->extra == extra) {
00746
00747
00748
00749
00750 RtlMoveMemory(pdesk->pLog + ind,
00751 pdesk->pLog + ind + 1,
00752 (pdesk->nLogCrt - ind - 1) *
sizeof(LogD));
00753
00754 (pdesk->nLogCrt)--;
00755
00756 (pdesk->nLockCount)--;
00757
00758
if (pdesk->nLockCount == 0) {
00759 RIPMSG1(RIP_VERBOSE,
"Lock count 0 for pdesk %#p\n", pdesk);
00760 }
00761
00762
return;
00763 }
00764 }
00765
00766
00767
00768
00769
00770 RIPMSG3(RIP_WARNING,
"Didn't find matching lock for pdesk %#p tag %d extra %lx\n",
00771 pdesk, tag, extra);
00772 }
00773 (pdesk->nLockCount)--;
00774
00775
goto growAndAdd;
00776
00777
return;
00778 }
00779
00780
#endif // LOGDESKTOPLOCKS