00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "psp.h"
00023
00024
#ifdef ALLOC_PRAGMA
00025
#pragma alloc_text(PAGE, NtOpenProcess)
00026
#pragma alloc_text(PAGE, NtOpenThread)
00027
#endif
00028
00029
NTSTATUS
00030 NtOpenProcess (
00031 OUT PHANDLE ProcessHandle,
00032 IN ACCESS_MASK DesiredAccess,
00033 IN POBJECT_ATTRIBUTES ObjectAttributes,
00034 IN PCLIENT_ID ClientId OPTIONAL
00035 )
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 {
00072
00073 HANDLE
Handle;
00074
KPROCESSOR_MODE PreviousMode;
00075
NTSTATUS Status;
00076
PEPROCESS Process;
00077
PETHREAD Thread;
00078 CLIENT_ID CapturedCid;
00079 BOOLEAN ObjectNamePresent;
00080 BOOLEAN ClientIdPresent;
00081
ACCESS_STATE AccessState;
00082
AUX_ACCESS_DATA AuxData;
00083 ULONG Attributes;
00084
00085
PAGED_CODE();
00086
00087
00088
00089
00090
00091
00092 PreviousMode = KeGetPreviousMode();
00093
if (PreviousMode !=
KernelMode) {
00094
00095
00096
00097
00098
00099
00100
try {
00101
00102
ProbeForWriteHandle(ProcessHandle);
00103
00104
ProbeForRead(
ObjectAttributes,
00105
sizeof(OBJECT_ATTRIBUTES),
00106
sizeof(ULONG));
00107 ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT(
ObjectAttributes->ObjectName);
00108 Attributes =
ObjectAttributes->Attributes;
00109
00110
if (ARGUMENT_PRESENT(ClientId)) {
00111
ProbeForRead(ClientId,
sizeof(CLIENT_ID),
sizeof(ULONG));
00112 CapturedCid = *ClientId;
00113 ClientIdPresent =
TRUE;
00114 }
00115
else {
00116 ClientIdPresent =
FALSE;
00117 }
00118 }
00119 except(
EXCEPTION_EXECUTE_HANDLER) {
00120
return GetExceptionCode();
00121 }
00122 }
00123
else {
00124 ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT(
ObjectAttributes->ObjectName);
00125 Attributes =
ObjectAttributes->Attributes;
00126
if (ARGUMENT_PRESENT(ClientId)) {
00127 CapturedCid = *ClientId;
00128 ClientIdPresent =
TRUE;
00129 }
00130
else {
00131 ClientIdPresent =
FALSE;
00132 }
00133 }
00134
00135
if ( ObjectNamePresent && ClientIdPresent ) {
00136
return STATUS_INVALID_PARAMETER_MIX;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
Status =
SeCreateAccessState(
00148 &AccessState,
00149 &AuxData,
00150 DesiredAccess,
00151 &
PsProcessType->
TypeInfo.
GenericMapping
00152 );
00153
00154
if ( !
NT_SUCCESS(
Status) ) {
00155
00156
return Status;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
if (
SeSinglePrivilegeCheck(
SeDebugPrivilege, PreviousMode )) {
00170
00171
if ( AccessState.
RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
00172 AccessState.
PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
00173
00174 }
else {
00175
00176 AccessState.
PreviouslyGrantedAccess |= ( AccessState.
RemainingDesiredAccess );
00177 }
00178
00179 AccessState.
RemainingDesiredAccess = 0;
00180
00181 }
00182
00183
if ( ObjectNamePresent ) {
00184
00185
00186
00187
00188
00189
00190
Status =
ObOpenObjectByName(
00191
ObjectAttributes,
00192
PsProcessType,
00193 PreviousMode,
00194 &AccessState,
00195 0,
00196
NULL,
00197 &
Handle
00198 );
00199
00200
SeDeleteAccessState( &AccessState );
00201
00202
if (
NT_SUCCESS(
Status) ) {
00203
try {
00204 *ProcessHandle =
Handle;
00205 }
00206 except(
EXCEPTION_EXECUTE_HANDLER) {
00207
return Status;
00208 }
00209 }
00210
00211
return Status;
00212 }
00213
00214
if ( ClientIdPresent ) {
00215
00216 Thread =
NULL;
00217
if (CapturedCid.UniqueThread) {
00218
Status =
PsLookupProcessThreadByCid(
00219 &CapturedCid,
00220 &Process,
00221 &Thread
00222 );
00223
00224
if ( !
NT_SUCCESS(
Status) ) {
00225
SeDeleteAccessState( &AccessState );
00226
return Status;
00227 }
00228 }
00229
else {
00230
Status =
PsLookupProcessByProcessId(
00231 CapturedCid.UniqueProcess,
00232 &Process
00233 );
00234
00235
if ( !
NT_SUCCESS(
Status) ) {
00236
SeDeleteAccessState( &AccessState );
00237
return Status;
00238 }
00239 }
00240
00241
00242
00243
00244
00245
Status =
ObOpenObjectByPointer(
00246 Process,
00247 Attributes,
00248 &AccessState,
00249 0,
00250
PsProcessType,
00251 PreviousMode,
00252 &
Handle
00253 );
00254
00255
SeDeleteAccessState( &AccessState );
00256
00257
if ( Thread ) {
00258
ObDereferenceObject(Thread);
00259 }
00260
ObDereferenceObject(Process);
00261
00262
if (
NT_SUCCESS(
Status) ) {
00263
00264
try {
00265 *ProcessHandle =
Handle;
00266 }
00267 except(
EXCEPTION_EXECUTE_HANDLER) {
00268
return Status;
00269 }
00270 }
00271
00272
return Status;
00273
00274 }
00275
00276
return STATUS_INVALID_PARAMETER_MIX;
00277 }
00278
00279
NTSTATUS
00280 NtOpenThread (
00281 OUT PHANDLE ThreadHandle,
00282 IN ACCESS_MASK DesiredAccess,
00283 IN POBJECT_ATTRIBUTES ObjectAttributes,
00284 IN PCLIENT_ID ClientId OPTIONAL
00285 )
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 {
00321
00322 HANDLE
Handle;
00323
KPROCESSOR_MODE PreviousMode;
00324
NTSTATUS Status;
00325
PETHREAD Thread;
00326 CLIENT_ID CapturedCid;
00327 BOOLEAN ObjectNamePresent;
00328 BOOLEAN ClientIdPresent;
00329
ACCESS_STATE AccessState;
00330
AUX_ACCESS_DATA AuxData;
00331 ULONG HandleAttributes;
00332
00333
PAGED_CODE();
00334
00335
00336
00337
00338
00339
00340 PreviousMode = KeGetPreviousMode();
00341
if (PreviousMode !=
KernelMode) {
00342
00343
00344
00345
00346
00347
00348
try {
00349
00350
ProbeForWriteHandle(
ThreadHandle);
00351
00352
ProbeForRead(
ObjectAttributes,
00353
sizeof(OBJECT_ATTRIBUTES),
00354
sizeof(ULONG));
00355 ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT(
ObjectAttributes->ObjectName);
00356 HandleAttributes =
ObjectAttributes->Attributes;
00357
00358
if (ARGUMENT_PRESENT(ClientId)) {
00359
ProbeForRead(ClientId,
sizeof(CLIENT_ID),
sizeof(ULONG));
00360 CapturedCid = *ClientId;
00361 ClientIdPresent =
TRUE;
00362 }
00363
else {
00364 ClientIdPresent =
FALSE;
00365 }
00366 }
00367 except(
EXCEPTION_EXECUTE_HANDLER) {
00368
return GetExceptionCode();
00369 }
00370 }
00371
else {
00372 ObjectNamePresent = (BOOLEAN) ARGUMENT_PRESENT(
ObjectAttributes->ObjectName);
00373 HandleAttributes =
ObjectAttributes->Attributes;
00374
if (ARGUMENT_PRESENT(ClientId)) {
00375 CapturedCid = *ClientId;
00376 ClientIdPresent =
TRUE;
00377 }
00378
else {
00379 ClientIdPresent =
FALSE;
00380 }
00381 }
00382
00383
if ( ObjectNamePresent && ClientIdPresent ) {
00384
return STATUS_INVALID_PARAMETER_MIX;
00385 }
00386
00387
Status =
SeCreateAccessState(
00388 &AccessState,
00389 &AuxData,
00390 DesiredAccess,
00391 &
PsProcessType->
TypeInfo.
GenericMapping
00392 );
00393
00394
if ( !
NT_SUCCESS(
Status) ) {
00395
00396
return Status;
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
if (
SeSinglePrivilegeCheck(
SeDebugPrivilege, PreviousMode )) {
00407
00408
if ( AccessState.
RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
00409 AccessState.
PreviouslyGrantedAccess |= THREAD_ALL_ACCESS;
00410
00411 }
else {
00412
00413 AccessState.
PreviouslyGrantedAccess |= ( AccessState.
RemainingDesiredAccess );
00414 }
00415
00416 AccessState.
RemainingDesiredAccess = 0;
00417
00418 }
00419
00420
if ( ObjectNamePresent ) {
00421
00422
00423
00424
00425
00426
00427
Status =
ObOpenObjectByName(
00428
ObjectAttributes,
00429
PsThreadType,
00430 PreviousMode,
00431 &AccessState,
00432 0,
00433
NULL,
00434 &
Handle
00435 );
00436
00437
SeDeleteAccessState( &AccessState );
00438
00439
if (
NT_SUCCESS(
Status) ) {
00440
try {
00441 *
ThreadHandle =
Handle;
00442 }
00443 except(
EXCEPTION_EXECUTE_HANDLER) {
00444
return Status;
00445 }
00446 }
00447
return Status;
00448 }
00449
00450
if ( ClientIdPresent ) {
00451
00452
if ( CapturedCid.UniqueProcess ) {
00453
Status =
PsLookupProcessThreadByCid(
00454 &CapturedCid,
00455
NULL,
00456 &Thread
00457 );
00458
00459
if ( !
NT_SUCCESS(
Status) ) {
00460
SeDeleteAccessState( &AccessState );
00461
return Status;
00462 }
00463 }
00464
else {
00465
Status =
PsLookupThreadByThreadId(
00466 CapturedCid.UniqueThread,
00467 &Thread
00468 );
00469
00470
if ( !
NT_SUCCESS(
Status) ) {
00471
SeDeleteAccessState( &AccessState );
00472
return Status;
00473 }
00474
00475 }
00476
00477
Status =
ObOpenObjectByPointer(
00478 Thread,
00479 HandleAttributes,
00480 &AccessState,
00481 0,
00482
PsThreadType,
00483 PreviousMode,
00484 &
Handle
00485 );
00486
00487
SeDeleteAccessState( &AccessState );
00488
ObDereferenceObject(Thread);
00489
00490
if (
NT_SUCCESS(
Status) ) {
00491
00492
try {
00493 *
ThreadHandle =
Handle;
00494 }
00495 except(
EXCEPTION_EXECUTE_HANDLER) {
00496
return Status;
00497 }
00498 }
00499
00500
return Status;
00501
00502 }
00503
00504
return STATUS_INVALID_PARAMETER_MIX;
00505 }