PspSetQuotaLimits
NTSTATUS __stdcall PspSetQuotaLimits(
VOID *ProcessHandle,
VOID *ProcessInformation,
UINT64 ProcessInformationLength,
INT8 PreviousMode){
int v5;
char v8;
NTSTATUS result;
unsigned int v10;
NTSTATUS v11;
UINT8 v12;
char v13;
_QWORD *v14;
INT64 v15;
__int64 v16;
int v17;
bool v18;
int v19;
_EPROCESS *v20;
VOID *v21;
UINT64 Tag;
UINT64 Taga;
char v24;
char v25;
UINT8 IncreaseOccurred;
char v27;
PVOID Object;
_ETHREAD *CurrentThread;
_QWORD *v30;
_BYTE QuotaLimits[88];
_SECURITY_SUBJECT_CONTEXT SubjectContext;
char Privileges[24];
_KAPC_STATE ApcState;
v5 = ProcessInformationLength;
v8 = 0;
Object = 0i64;
memset(QuotaLimits, 0i64, sizeof(QuotaLimits));
memset(&ApcState, 0, sizeof(ApcState));
IncreaseOccurred = 0;
memset(&SubjectContext, 0, sizeof(SubjectContext));
memset(Privileges, 0, sizeof(Privileges));
if( v5 == 48 )
{
*(_OWORD *)QuotaLimits = *(_OWORD *)ProcessInformation;
*(_OWORD *)&QuotaLimits[16] = *((_OWORD *)ProcessInformation + 1);
*(_OWORD *)&QuotaLimits[32] = *((_OWORD *)ProcessInformation + 2);
memset(&QuotaLimits[48], 0, 40);
v24 = 1;
}
else
{
if( v5 != 88 )
return -1073741820;
v24 = 0;
*(_OWORD *)QuotaLimits = *(_OWORD *)ProcessInformation;
*(_OWORD *)&QuotaLimits[16] = *((_OWORD *)ProcessInformation + 1);
*(_OWORD *)&QuotaLimits[32] = *((_OWORD *)ProcessInformation + 2);
*(_OWORD *)&QuotaLimits[48] = *((_OWORD *)ProcessInformation + 3);
*(_OWORD *)&QuotaLimits[64] = *((_OWORD *)ProcessInformation + 4);
*(_QWORD *)&QuotaLimits[80] = *((_QWORD *)ProcessInformation + 10);
}
if( (*(_DWORD *)&QuotaLimits[80] & 0xFFFFFFE0) != 0 || (QuotaLimits[80] & 3) == 3 || (QuotaLimits[80] & 0xC) == 12 )
return -1073741811;
if( (QuotaLimits[80] & 1) != 0 )
{
v10 = 4;
}
else
{
v10 = 0;
if( (QuotaLimits[80] & 2) != 0 )
v10 = 8;
}
if( (QuotaLimits[80] & 4) != 0 )
{
v10 |= 1u;
}
else if( (QuotaLimits[80] & 8) != 0 )
{
v10 |= 2u;
}
if( *(_QWORD *)&QuotaLimits[56] | *(_QWORD *)&QuotaLimits[64] | *(_QWORD *)&QuotaLimits[72] | *(unsigned int *)&QuotaLimits[84] )
return -1073741811;
LODWORD(Tag) = 2035381072;
result = ObReferenceObjectByHandleWithTag(
ProcessHandle,
0x100ui64,
(_OBJECT_TYPE *)PsProcessType,
PreviousMode,
Tag,
&Object,
0i64);
if( result >= 0 )
{
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v11 = 0;
if( *((_UNKNOWN **)Object + 173) != &unk_140C537C0 || *(_QWORD *)&QuotaLimits[16] && *(_QWORD *)&QuotaLimits[24] )
{
if( *(_QWORD *)&QuotaLimits[16] && *(_QWORD *)&QuotaLimits[24] )
{
if( *(_QWORD *)&QuotaLimits[16] == -1i64 && *(_QWORD *)&QuotaLimits[24] == -1i64 )
{
v25 = 1;
v12 = 0;
v27 = 0;
}
else
{
v25 = 0;
v12 = PspSinglePrivCheck(*(__int64 *)&QuotaLimits[24], -1i64, PreviousMode, (__int64)&SubjectContext);
v27 = 1;
}
v13 = 0;
v14 = Object;
v30 = Object;
while( 1 )
{
KeStackAttachProcess((PRKPROCESS)Object, &ApcState);
--CurrentThread->Tcb.SpecialApcDisable;
v16 = v14[162];
if( v16 )
{
ExAcquireResourceExclusiveLite(v16 + 56, 1, v15);
if( (*(_DWORD *)(v16 + 848) & 1) != 0 )
{
v10 = 1;
v12 = 1;
v8 = 1;
if( !v25 )
{
*(_QWORD *)&QuotaLimits[16] = *(_QWORD *)(v16 + 792);
*(_QWORD *)&QuotaLimits[24] = *(_QWORD *)(v16 + 800);
}
}
PspLockWorkingSetChangeExclusiveUnsafe();
ExReleaseResourceLite((PERESOURCE)(v16 + 56));
}
LODWORD(Taga) = v10;
MmAdjustWorkingSetSizeEx(
*(UINT64 *)&QuotaLimits[16],
*(UINT64 *)&QuotaLimits[24],
WorkingSetTypeUser,
v12,
Taga,
&IncreaseOccurred);
v11 = v17;
if( v17 < 0 && v8 == 1 )
MmEnforceWorkingSetLimit((_EPROCESS *)Object, v10);
if( v16 )
PspUnlockWorkingSetChangeExclusiveUnsafe();
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
KeUnstackDetachProcess(&ApcState);
if( IncreaseOccurred == 1 && !v8 )
v13 = 1;
v18 = v30[162] == v16;
v14 = v30;
if( v18 )
break;
v8 = 0;
}
if( v27 == 1 && Privileges[20] )
{
if( v13 == 1 )
SePrivilegedServiceAuditAlarm(
(_UNICODE_STRING *)&PspWorkingSetAdjustService,
&SubjectContext,
(PRIVILEGE_SET *)Privileges,
Privileges[21]);
SeReleaseSubjectContext(&SubjectContext);
}
}
}
else
{
if( v24 == 1 )
{
memset(QuotaLimits, 0i64, sizeof(QuotaLimits));
*(_DWORD *)&QuotaLimits[80] = 16;
}
if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeIncreaseQuotaPrivilege, PreviousMode) )
{
v19 = -1073741727;
LABEL_53:
ObfDereferenceObjectWithTag(Object, 0x79517350ui64);
return v19;
}
v20 = (_EPROCESS *)Object;
v21 = PsReferencePrimaryToken((_EPROCESS *)Object);
v19 = PspAssignProcessQuotaBlock((_QUOTA_LIMITS_EX *)QuotaLimits, v20, v21);
ObFastDereferenceObject(&v20->Token, v21);
if( v19 < 0 )
goto LABEL_53;
}
ObfDereferenceObjectWithTag(Object, 0x79517350ui64);
return v11;
}
return result;
}Referenced by:
NtSetInformationProcess