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


Generated on Sat May 15 19:45:23 2004 for test by doxygen 1.3.7