PsImpersonateClient
NTSTATUS __stdcall PsImpersonateClient(
PETHREAD Thread,
VOID *Token,
BOOL CopyOnOpen,
BOOL EffectiveOnly,
_SECURITY_IMPERSONATION_LEVEL ImpersonationLevel){
_EPROCESS *Process;
char v6;
unsigned __int64 v9;
_ADAPTER_OBJECT *v11;
_ADAPTER_OBJECT *AdjustedClientToken;
_ETHREAD *CurrentThread;
char v14;
bool v15;
_ETHREAD *v16;
_EX_FAST_REF *p_Token;
VOID *v18;
_SECURITY_IMPERSONATION_LEVEL v19;
UINT8 v20;
char v21;
_ETHREAD *v22;
unsigned __int64 v23;
char v24;
VOID **DuplicateToken;
VOID *v27;
UINT8 v28;
int v29;
_SECURITY_IMPERSONATION_LEVEL v30;
_EX_PUSH_LOCK *p_ProcessLock;
char UseProcessTrust;
_KTHREAD *Threada;
Process = Thread->Tcb.Process;
v6 = 0;
UseProcessTrust = 0;
v9 = (unsigned __int64)Token;
if( !Token )
{
v11 = 0i64;
AdjustedClientToken = 0i64;
if( (Thread->CrossThreadFlags & 8) == 0 )
return 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--CurrentThread->Tcb.KernelApcDisable;
ExAcquirePushLockExclusiveEx(&Thread->ThreadLock, 0i64);
if( (Thread->CrossThreadFlags & 8) != 0 )
{
AdjustedClientToken = (_ADAPTER_OBJECT *)Thread->AdjustedClientToken;
v11 = (_ADAPTER_OBJECT *)(Thread->ClientSecurity.ImpersonationData & 0xFFFFFFFFFFFFFFF8ui64);
Thread->AdjustedClientToken = 0i64;
_InterlockedAnd((volatile signed __int32 *)&Thread->1296, 0xFFFFFFF7);
}
v14 = _InterlockedExchangeAdd64(&Thread->ThreadLock._bf_0, 0xFFFFFFFFFFFFFFFFui64);
if( (v14 & 2) != 0 && (v14 & 4) == 0 )
ExfTryToWakePushLock(&Thread->ThreadLock);
KeAbPostRelease(&Thread->ThreadLock);
v15 = CurrentThread->Tcb.KernelApcDisable++ == -1;
if( v15
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152
&& !CurrentThread->Tcb.SpecialApcDisable )
{
KiCheckForKernelApcDelivery();
}
v16 = CurrentThread;
LABEL_21:
PspWriteTebImpersonationInfo(Thread, v16);
if( v11 )
HalPutDmaAdapter(v11);
if( AdjustedClientToken )
HalPutDmaAdapter(AdjustedClientToken);
return 0;
}
p_Token = &Process->Token;
v18 = ObFastReferenceObject(&Process->Token);
if( !v18 )
{
Threada = (_ETHREAD *)KeGetCurrentThread();
--Threada->Tcb.KernelApcDisable;
p_ProcessLock = &Process->ProcessLock;
ExAcquirePushLockSharedEx(p_ProcessLock, 0i64);
v18 = ObFastReferenceObjectLocked(p_Token);
if( _InterlockedCompareExchange64(&p_ProcessLock->_bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(p_ProcessLock);
KeAbPostRelease(p_ProcessLock);
KeLeaveCriticalRegionThread(&Threada->Tcb);
if( !v18 )
{
v21 = ImpersonationLevel;
goto LABEL_13;
}
}
v19 = ImpersonationLevel;
LODWORD(Threada) = ImpersonationLevel;
if( SeTokenCanImpersonate(v18, (VOID *)v9, ImpersonationLevel, (UINT8 *)&UseProcessTrust) < 0 )
{
v15 = *(_DWORD *)(v9 + 192) == 2;
v30 = SecurityIdentification;
LODWORD(Threada) = 1;
if( v15 && *(int *)(v9 + 196) < 1 )
{
v30 = *(_DWORD *)(v9 + 196);
LODWORD(Threada) = v30;
}
v29 = SeCopyClientToken((VOID *)v9, v30, v20, 0i64, 0i64);
if( v29 >= 0 )
{
v9 = 0i64;
v6 = 1;
goto LABEL_12;
}
}
else
{
if( !UseProcessTrust )
goto LABEL_12;
DuplicateToken = (VOID **)SeQueryTokenTrustSid(v18);
LOBYTE(v27) = 1;
v29 = SeCopyClientToken((VOID *)v9, v19, v28, v27, DuplicateToken);
if( v29 >= 0 )
{
if( CopyOnOpen )
{
SeSetTokenTrustLink(0i64, (VOID *)v9);
}
else
{
v9 = 0i64;
v6 = 1;
}
LABEL_12:
ObFastDereferenceObject(p_Token, v18);
v15 = v6 == 0;
v21 = (char)Threada;
if( !v15 )
{
LABEL_14:
v22 = (_ETHREAD *)KeGetCurrentThread();
v23 = v9 & 0xFFFFFFFFFFFFFFF8ui64 | v21 & 3 | (4i64 * EffectiveOnly);
--v22->Tcb.KernelApcDisable;
ExAcquirePushLockExclusiveEx(&Thread->ThreadLock, 0i64);
if( (Thread->CrossThreadFlags & 8) != 0 )
{
AdjustedClientToken = (_ADAPTER_OBJECT *)Thread->AdjustedClientToken;
v11 = (_ADAPTER_OBJECT *)(Thread->ClientSecurity.ImpersonationData & 0xFFFFFFFFFFFFFFF8ui64);
}
else
{
v11 = 0i64;
AdjustedClientToken = 0i64;
_InterlockedOr((volatile signed __int32 *)&Thread->1296, 8u);
}
Thread->AdjustedClientToken = 0i64;
Thread->ClientSecurity.ImpersonationData = v23;
if( CopyOnOpen )
_InterlockedOr((volatile signed __int32 *)&Thread->1296, 0x100u);
else
_InterlockedAnd((volatile signed __int32 *)&Thread->1296, 0xFFFFFEFF);
v24 = _InterlockedExchangeAdd64(&Thread->ThreadLock._bf_0, 0xFFFFFFFFFFFFFFFFui64);
if( (v24 & 2) != 0 && (v24 & 4) == 0 )
ExfTryToWakePushLock(&Thread->ThreadLock);
KeAbPostRelease(&Thread->ThreadLock);
v15 = v22->Tcb.KernelApcDisable++ == -1;
if( v15
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v22->Tcb.ApcState.ApcListHead[0].Flink != &v22->Tcb.152
&& !v22->Tcb.SpecialApcDisable )
{
KiCheckForKernelApcDelivery();
}
v16 = v22;
goto LABEL_21;
}
LABEL_13:
ObfReferenceObject((PVOID)v9);
goto LABEL_14;
}
}
ObFastDereferenceObject(p_Token, v18);
return v29;
}Referenced by:
AlpcpImpersonateMessage
CmpCmdHiveOpen
CmpOpenHiveFile
NtImpersonateAnonymousToken
PsAssignImpersonationToken
PsRevertThreadToSelf
PsRevertToSelf
SeImpersonateClientEx