test: psopen.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# psopen.c File Reference

`#include "psp.h"`

Go to the source code of this file.

## Functions

NTSTATUS | NtOpenProcess (OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL)
NTSTATUS | NtOpenThread (OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL)

## Function Documentation

NTSTATUS NtOpenProcess | ( | OUT PHANDLE | ProcessHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | IN PCLIENT_ID ClientId | OPTIONAL
| ) |

Definition at line 30 of file psopen.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _OBJECT_TYPE_INITIALIZER::GenericMapping, Handle, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObjectAttributes, ObOpenObjectByName(), ObOpenObjectByPointer(), PAGED_CODE, _ACCESS_STATE::PreviouslyGrantedAccess, ProbeForRead, ProbeForWriteHandle, PsLookupProcessByProcessId(), PsLookupProcessThreadByCid(), PsProcessType, _ACCESS_STATE::RemainingDesiredAccess, SeCreateAccessState(), SeDebugPrivilege, SeDeleteAccessState(), SeSinglePrivilegeCheck(), Status, TRUE, and _OBJECT_TYPE::TypeInfo.

Referenced by OpenAppropriateToken(), and RtlpChangeQueryDebugBufferTarget().

    00039                    :
    00040
    00041     This function opens a handle to a process object with the specified
    00042     desired access.
    00043
    00044     The object is located either by name, or by locating a thread whose
    00045     Client ID matches the specified Client ID and then opening that thread's
    00046     process.
    00047
    00048 Arguments:
    00049
    00050     ProcessHandle - Supplies a pointer to a variable that will receive
    00051         the process object handle.
    00052
    00053     DesiredAccess - Supplies the desired types of access for the process
    00054         object.
    00055
    00056     ObjectAttributes - Supplies a pointer to an object attributes structure.
    00057         If the ObjectName field is specified, then ClientId must not be
    00058         specified.
    00059
    00060     ClientId - Supplies a pointer to a ClientId that if supplied
    00061         specifies the thread whose process is to be opened. If this
    00062         argument is specified, then ObjectName field of the ObjectAttributes
    00063         structure must not be specified.
    00064
    00065 Return Value:
    00066
    00067     TBS
    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     // Make sure that only one of either ClientId or ObjectName is
    00089     // present.
    00090     //
    00091
    00092     PreviousMode = KeGetPreviousMode();
    00093     if (PreviousMode != KernelMode) {
    00094
    00095         //
    00096         // Since we need to look at the ObjectName field, probe
    00097         // ObjectAttributes and capture object name present indicator.
    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     // Create an AccessState here, because the caller may have
    00141     // DebugPrivilege, which requires us to make special adjustments
    00142     // to his desired access mask.  We do this by modifying the
    00143     // internal fields in the AccessState to achieve the effect
    00144     // we desire.
    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     // Check here to see if the caller has SeDebugPrivilege.  If
    00161     // he does, we will allow him any access he wants to the process.
    00162     // We do this by clearing the DesiredAccess in the AccessState
    00163     // and recording what we want him to have in the PreviouslyGrantedAccess
    00164     // field.
    00165     //
    00166     // Note that this routine performs auditing as appropriate.
    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         // Open handle to the process object with the specified desired access,
    00187         // set process handle value, and return service completion status.
    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         // OpenObjectByAddress
    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 }

NTSTATUS NtOpenThread | ( | OUT PHANDLE | ThreadHandle,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN POBJECT_ATTRIBUTES | ObjectAttributes,
|  | IN PCLIENT_ID ClientId | OPTIONAL
| ) |

Definition at line 280 of file psopen.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _OBJECT_TYPE_INITIALIZER::GenericMapping, Handle, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObjectAttributes, ObOpenObjectByName(), ObOpenObjectByPointer(), PAGED_CODE, _ACCESS_STATE::PreviouslyGrantedAccess, ProbeForRead, ProbeForWriteHandle, PsLookupProcessThreadByCid(), PsLookupThreadByThreadId(), PsProcessType, PsThreadType, _ACCESS_STATE::RemainingDesiredAccess, SeCreateAccessState(), SeDebugPrivilege, SeDeleteAccessState(), SeSinglePrivilegeCheck(), Status, ThreadHandle, TRUE, and _OBJECT_TYPE::TypeInfo.

Referenced by SepServerInitialize().

    00289                    :
    00290
    00291     This function opens a handle to a thread object with the specified
    00292     desired access.
    00293
    00294     The object is located either by name, or by locating a thread whose
    00295     Client ID matches the specified Client ID.
    00296
    00297 Arguments:
    00298
    00299     ThreadHandle - Supplies a pointer to a variable that will receive
    00300         the thread object handle.
    00301
    00302     DesiredAccess - Supplies the desired types of access for the Thread
    00303         object.
    00304
    00305     ObjectAttributes - Supplies a pointer to an object attributes structure.
    00306         If the ObjectName field is specified, then ClientId must not be
    00307         specified.
    00308
    00309     ClientId - Supplies a pointer to a ClientId that if supplied
    00310         specifies the thread whose thread is to be opened. If this
    00311         argument is specified, then ObjectName field of the ObjectAttributes
    00312         structure must not be specified.
    00313
    00314 Return Value:
    00315
    00316     TBS
    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     // Make sure that only one of either ClientId or ObjectName is
    00337     // present.
    00338     //
    00339
    00340     PreviousMode = KeGetPreviousMode();
    00341     if (PreviousMode != KernelMode) {
    00342
    00343         //
    00344         // Since we need to look at the ObjectName field, probe
    00345         // ObjectAttributes and capture object name present indicator.
    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     // Check here to see if the caller has SeDebugPrivilege.  If
    00401     // he does, we will allow him any access he wants to the process.
    00402     // We do this by clearing the DesiredAccess in the AccessState
    00403     // and recording what we want him to have in the PreviouslyGrantedAccess
    00404     // field.
    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         // Open handle to the Thread object with the specified desired access,
    00424         // set Thread handle value, and return service completion status.
    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 }
    }