SepAccessCheck

NTSTATUS __stdcall SepAccessCheck(
        VOID *SecurityDescriptor,
        VOID *PrincipalSelfSid,
        _TOKEN *PrimaryToken,
        _TOKEN *ClientToken,
        UINT64 DesiredAccess,
        _IOBJECT_TYPE_LIST *ObjectTypeList,
        UINT64 ObjectTypeListLength,
        _GENERIC_MAPPING *GenericMapping,
        UINT64 PreviouslyGrantedAccess,
        CHAR PreviousMode,
        UINT64 *GrantedAccess,
        _PRIVILEGE_SET **Privileges,
        INT64 *AccessStatus,
        UINT8 ReturnResultList,
        UINT8 TokenIsOwner,
        _SE_PACKAGE_CAPABILITY_INFO *PackageCapabilityInfo,
        _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION **ResourceInfo,
        UINT8 *ReturnSomeAccessGranted,
        UINT8 *ReturnSomeAccessDenied){
  unsigned int v19; 
  _PRIVILEGE_SET **v20; 
  _SE_PACKAGE_CAPABILITY_INFO *v22; 
  int v24; 
  unsigned int v25; 
  int v26; 
  __int16 v27; 
  __int64 v28; 
  _ACL *v29; 
  _ACL *Sacl; 
  int v31; 
  int v32; 
  _IOBJECT_TYPE_LIST *v33; 
  int v34; 
  _IOBJECT_TYPE_LIST *v35; 
  _SE_PACKAGE_CAPABILITY_INFO *v36; 
  unsigned int v37; 
  unsigned int v38; 
  int v39; 
  unsigned int v40; 
  UINT8 v41; 
  int v42; 
  unsigned __int8 v43; 
  int v45; 
  __int64 v46; 
  unsigned int v47; 
  _DWORD *v48; 
  _IOBJECT_TYPE_LIST v49; 
  int v50; 
  int v51; 
  int v52; 
  int v53; 
  unsigned int v54; 
  UINT8 v55; 
  unsigned int Remaining; 
  unsigned int v57; 
  unsigned __int8 v58; 
  _SE_PACKAGE_CAPABILITY_INFO *v59; 
  unsigned int TokenFlags; 
  UINT8 v61; 
  UINT8 v62; 
  int v63; 
  int v64; 
  INT64 *v65; 
  __int64 v66; 
  bool v67; 
  int v68; 
  UINT64 *v69; 
  unsigned int v70; 
  unsigned int v71; 
  __int64 v72; 
  __int64 v73; 
  INT64 *v74; 
  unsigned __int64 k; 
  UINT64 *v76; 
  __int64 v77; 
  __int64 v78; 
  __int64 v79; 
  INT64 *v80; 
  unsigned __int64 i; 
  UINT64 *v82; 
  unsigned __int64 j; 
  UINT64 *v84; 
  __int64 v85; 
  VOID *PrincipalSelfSida; 
  VOID *PrincipalSelfSidb; 
  UINT64 LocalTypeListLength; 
  UINT64 LocalTypeListLengtha; 
  _IOBJECT_TYPE_LIST *LocalTypeList; 
  _IOBJECT_TYPE_LIST *LocalTypeLista; 
  UINT64 RestrictionMask; 
  UINT64 RestrictionMaska; 
  UINT64 RestrictionMaskb; 
  UINT8 v95; 
  UINT8 v96; 
  UINT8 v97; 
  UINT8 v98; 
  UINT8 v99; 
  unsigned int PrivilegeCount; 
  unsigned int PrivilegeCount_4; 
  unsigned int v102; 
  _IOBJECT_TYPE_LIST *v103; 
  _LUID_AND_ATTRIBUTES RequiredPrivileges; 
  _IOBJECT_TYPE_LIST v107[4]; 
  __int128 v108; 
  __int128 v109; 

  v19 = 0;
  v20 = Privileges;
  v22 = PackageCapabilityInfo;
  if( !ClientToken )
    ClientToken = PrimaryToken;
  v103 = ObjectTypeList;
  v24 = DesiredAccess;
  v25 = DesiredAccess;
  PrivilegeCount = 0;
  v99 = 0;
  v96 = 0;
  v98 = 0;
  PrivilegeCount_4 = DesiredAccess;
  v102 = 1;
  *(_OWORD *)v107 = 0i64;
  v108 = 0i64;
  v109 = 0i64;
  if( (DesiredAccess & 0x1000000) != 0 )
  {
    RequiredPrivileges.Luid = SeSecurityPrivilege;
    RequiredPrivileges.Attributes = 0;
    if( !SepPrivilegeCheck(ClientToken, &RequiredPrivileges, 1ui64, 1ui64, PreviousMode) )
    {
      v26 = 0;
      v42 = -1073741727;
      v43 = v58;
LABEL_33:
      if( ReturnResultList )
      {
        if( (_DWORD)ObjectTypeListLength )
        {
          if( (unsigned int)ObjectTypeListLength >= 4 )
          {
            v78 = (unsigned int)(ObjectTypeListLength - 1);
            if( GrantedAccess > (UINT64 *)((char *)AccessStatus + 4 * v78)
              || (char *)GrantedAccess + 4 * v78 < (char *)AccessStatus )
            {
              v79 = (unsigned int)ObjectTypeListLength & 0xFFFFFFFC;
              do
                v19 += 4;
              while( v19 < (unsigned int)v79 );
              v80 = AccessStatus;
              for( i = (unsigned __int64)(4 * v79) >> 2; i; --i )
              {
                *(_DWORD *)v80 = v42;
                v80 = (INT64 *)((char *)v80 + 4);
              }
              v82 = GrantedAccess;
              for( j = (unsigned __int64)(4 * v79) >> 2; j; --j )
              {
                *(_DWORD *)v82 = v26;
                v82 = (UINT64 *)((char *)v82 + 4);
              }
            }
          }
          if( v19 < (unsigned int)ObjectTypeListLength )
          {
            v84 = &GrantedAccess[v19 / 2];
            v85 = (unsigned int)ObjectTypeListLength - v19;
            do
            {
              *(_DWORD *)((char *)v84 + (char *)AccessStatus - (char *)GrantedAccess) = v42;
              *(_DWORD *)v84 = v26;
              v84 = (UINT64 *)((char *)v84 + 4);
              --v85;
            }
            while( v85 );
          }
        }
        goto LABEL_35;
      }
LABEL_34:
      *(_DWORD *)AccessStatus = v42;
      *(_DWORD *)GrantedAccess = v26;
LABEL_35:
      if( v42 < 0 )
      {
        if( ReturnSomeAccessGranted )
          *ReturnSomeAccessGranted = 0;
        if( ReturnSomeAccessDenied )
          *ReturnSomeAccessDenied = 1;
      }
      else
      {
        if( ReturnSomeAccessGranted )
          *ReturnSomeAccessGranted = 1;
        if( ReturnSomeAccessDenied )
          *ReturnSomeAccessDenied = 0;
      }
      return v43;
    }
    v24 = DesiredAccess;
    v31 = 1;
    PrivilegeCount = 1;
    v25 = DesiredAccess & 0xFEFFFFFF;
    v99 = 1;
    v26 = PreviouslyGrantedAccess | 0x1000000;
    PrivilegeCount_4 = DesiredAccess & 0xFEFFFFFF;
    if( (DesiredAccess & 0xFEFFFFFF) == 0 )
      goto LABEL_46;
    v22 = PackageCapabilityInfo;
  }
  else
  {
    v26 = PreviouslyGrantedAccess;
  }
  v27 = *((_WORD *)SecurityDescriptor + 1);
  if( (v27 & 4) != 0 )
  {
    if( v27 >= 0 )
    {
      v29 = (_ACL *)*((_QWORD *)SecurityDescriptor + 4);
    }
    else
    {
      v28 = *((unsigned int *)SecurityDescriptor + 4);
      if( (_DWORD)v28 )
        v29 = (_ACL *)((char *)SecurityDescriptor + v28);
      else
        v29 = 0i64;
    }
  }
  else
  {
    v29 = 0i64;
  }
  if( (v27 & 0x10) != 0 )
  {
    if( v27 < 0 )
    {
      v46 = *((unsigned int *)SecurityDescriptor + 3);
      if( (_DWORD)v46 )
        Sacl = (_ACL *)((char *)SecurityDescriptor + v46);
      else
        Sacl = 0i64;
    }
    else
    {
      Sacl = (_ACL *)*((_QWORD *)SecurityDescriptor + 3);
    }
  }
  else
  {
    Sacl = 0i64;
  }
  if( (*((_WORD *)SecurityDescriptor + 1) & 4) == 0 || !v29 )
  {
    v45 = v26 | v24;
    v26 |= v24;
    if( (v24 & 0x2000000) != 0 )
      v26 = v45 & 0xFDFFFFFF | GenericMapping->GenericAll;
    if( (ClientToken->TokenFlags & 0x4000) != 0 )
    {
      v26 = 0;
      v22->PackageGrantedAccess = 0;
      BYTE1(v22[1].Remaining) = 0;
      goto LABEL_62;
    }
    v31 = PrivilegeCount;
LABEL_45:
    v20 = Privileges;
LABEL_46:
    v41 = 0;
    goto LABEL_29;
  }
  if( (v25 & 0x80000) == 0 )
  {
    v31 = PrivilegeCount;
LABEL_16:
    v32 = 1;
    goto LABEL_17;
  }
  RequiredPrivileges.Luid = (_LUID)SeTakeOwnershipPrivilege;
  RequiredPrivileges.Attributes = 0;
  if( SepPrivilegeCheck(ClientToken, &RequiredPrivileges, 1ui64, 1ui64, PreviousMode) )
  {
    v26 |= 0x80000u;
    v25 = PrivilegeCount_4 & 0xFFF7FFFF;
    v31 = PrivilegeCount + 1;
    PrivilegeCount_4 = v25;
    ++PrivilegeCount;
    v41 = 1;
    v96 = 1;
    if( !v25 )
    {
      v20 = Privileges;
      goto LABEL_29;
    }
    goto LABEL_16;
  }
  RequiredPrivileges.Luid = (_LUID)SeRelabelPrivilege;
  RequiredPrivileges.Attributes = 0;
  v55 = SepPrivilegeCheck(ClientToken, &RequiredPrivileges, 1ui64, 1ui64, PreviousMode);
  v25 = PrivilegeCount_4;
  v31 = PrivilegeCount;
  if( v55 )
  {
    v25 = PrivilegeCount_4 & 0xFFF7FFFF;
    v98 = v32;
    v31 = PrivilegeCount + 1;
    PrivilegeCount_4 = v25;
    v26 |= 0x80000u;
    ++PrivilegeCount;
    if( !v25 )
      goto LABEL_45;
  }
LABEL_17:
  if( !v29->AceCount )
  {
    v59 = PackageCapabilityInfo;
    PackageCapabilityInfo->UserGroupsRemaining = v25;
    TokenFlags = ClientToken->TokenFlags;
    if( (TokenFlags & 0x4000) != 0 )
    {
      v26 &= ~PackageCapabilityInfo->Remaining;
      v59 = PackageCapabilityInfo;
    }
    if( v25 == 0x2000000 )
    {
      if( v26 )
      {
LABEL_105:
        v20 = Privileges;
        v41 = v96;
        goto LABEL_29;
      }
    }
    else if( !v25 && v59->Remaining && v26 && (TokenFlags & 0x6000) == 0 )
    {
      goto LABEL_105;
    }
    v26 = 0;
    goto LABEL_62;
  }
  if( (_DWORD)ObjectTypeListLength )
  {
    v33 = ObjectTypeList;
    v32 = ObjectTypeListLength;
    v102 = ObjectTypeListLength;
  }
  else
  {
    v33 = v107;
    DWORD1(v108) = -1;
    v103 = v107;
  }
  v34 = DesiredAccess & 0x2000000;
  if( (DesiredAccess & 0x2000000) == 0 && !ReturnResultList )
  {
    LODWORD(RestrictionMask) = ObjectTypeListLength;
    LODWORD(LocalTypeListLength) = v32;
    SepNormalAccessCheck(
      v25,
      ClientToken,
      PrimaryToken,
      v29,
      Sacl,
      ResourceInfo,
      PrincipalSelfSid,
      LocalTypeListLength,
      v33,
      RestrictionMask,
      0,
      TokenIsOwner,
      PackageCapabilityInfo);
    v35 = v103;
    v36 = PackageCapabilityInfo;
    PackageCapabilityInfo->UserGroupsRemaining = v103[6];
    if( v103[6] )
      goto LABEL_67;
    v37 = ClientToken->TokenFlags;
    if( (v37 & 0x10) != 0 )
    {
      if( (v37 & 8) != 0 )
        v54 = GenericMapping->GenericWrite & ~(GenericMapping->GenericRead | GenericMapping->GenericExecute) | 0x10D0000;
      else
        v54 = GenericMapping->GenericAll | 0x1FFFFF;
      v39 = DesiredAccess;
      v38 = 0;
      if( (v54 & (unsigned int)DesiredAccess) == 0 )
      {
LABEL_26:
        v36->UserGroupsRemaining = v38;
        if( v35[6] )
          goto LABEL_67;
        v40 = ClientToken->TokenFlags;
        if( (v40 & 0x2000) != 0 )
        {
LABEL_28:
          v31 = PrivilegeCount;
          v26 |= v39;
          v41 = v96;
          v20 = Privileges;
          goto LABEL_29;
        }
        v50 = v39 | PrivilegeCount_4;
        if( (v40 & 0x4000) != 0 )
        {
          v51 = ~(v36->PackageGrantedAccess | v36->CapabilityGrantedAccess);
          v52 = v50 | v36->Remaining;
        }
        else
        {
          if( !LOBYTE(v36[1].Remaining) )
          {
            v53 = 0;
LABEL_66:
            v35[6] = v53;
            if( !v53 )
              goto LABEL_28;
LABEL_67:
            v42 = -1073741790;
            v26 = 0;
            v43 = 1;
            goto LABEL_34;
          }
          v51 = v50 | v36->Remaining;
          v52 = ~v36->PackageGrantedAccess;
        }
        v53 = v52 & v51;
        goto LABEL_66;
      }
      LODWORD(RestrictionMaska) = ObjectTypeListLength;
      LODWORD(LocalTypeListLengtha) = v102;
      SepNormalAccessCheck(
        v54 & PrivilegeCount_4,
        ClientToken,
        PrimaryToken,
        v29,
        Sacl,
        ResourceInfo,
        PrincipalSelfSid,
        LocalTypeListLengtha,
        v103,
        RestrictionMaska,
        1u,
        TokenIsOwner,
        PackageCapabilityInfo);
      v35 = v103;
      v36 = PackageCapabilityInfo;
      v38 = v103[6];
    }
    else
    {
      v38 = 0;
    }
    v39 = DesiredAccess;
    goto LABEL_26;
  }
  LODWORD(RestrictionMask) = 0;
  LODWORD(LocalTypeList) = ObjectTypeListLength;
  LODWORD(PrincipalSelfSida) = v32;
  SepMaximumAccessCheck(
    ClientToken,
    PrimaryToken,
    v29,
    Sacl,
    ResourceInfo,
    PrincipalSelfSid,
    (UINT64)PrincipalSelfSida,
    v33,
    (UINT64)LocalTypeList,
    RestrictionMask,
    0,
    TokenIsOwner,
    PackageCapabilityInfo);
  v47 = ClientToken->TokenFlags;
  if( (v47 & 0x10) != 0 )
  {
    if( (v47 & 8) != 0 )
      v57 = GenericMapping->GenericWrite & ~(GenericMapping->GenericRead | GenericMapping->GenericExecute) | 0x10D0000;
    else
      v57 = GenericMapping->GenericAll | 0x1FFFFF;
    LODWORD(RestrictionMaskb) = v57;
    LODWORD(LocalTypeLista) = ObjectTypeListLength;
    LODWORD(PrincipalSelfSidb) = v102;
    SepMaximumAccessCheck(
      ClientToken,
      PrimaryToken,
      v29,
      Sacl,
      ResourceInfo,
      PrincipalSelfSid,
      (UINT64)PrincipalSelfSidb,
      v103,
      (UINT64)LocalTypeLista,
      RestrictionMaskb,
      1u,
      TokenIsOwner,
      PackageCapabilityInfo);
    v47 = ClientToken->TokenFlags;
  }
  v48 = v103 + 7;
  v49 = v103[7];
  if( (v47 & 0x2000) == 0 )
  {
    if( (v47 & 0x4000) != 0 )
    {
      Remaining = PackageCapabilityInfo->Remaining;
      v49 &= PackageCapabilityInfo->PackageGrantedAccess | PackageCapabilityInfo->CapabilityGrantedAccess;
    }
    else
    {
      if( !LOBYTE(PackageCapabilityInfo[1].Remaining) )
        goto LABEL_54;
      v49 &= PackageCapabilityInfo->PackageGrantedAccess;
      Remaining = PackageCapabilityInfo->Remaining;
    }
    v26 &= ~Remaining;
  }
LABEL_54:
  if( !ReturnResultList )
  {
    if( (~(v49 | 0x2000000) & PrivilegeCount_4) != 0 )
      goto LABEL_67;
    v20 = Privileges;
    v26 |= v49;
    v31 = PrivilegeCount;
    v41 = v96;
LABEL_29:
    if( v26 )
    {
      v42 = 0;
      if( KeGetCurrentIrql() < 2u )
      {
        if( v31 )
        {
          SepAssemblePrivileges(PrivilegeCount, v99, v41, v98, v20);
          if( v20 )
          {
            if( !*v20 )
            {
              v43 = 0;
              v42 = -1073741801;
              v26 = 0;
              goto LABEL_33;
            }
          }
        }
      }
LABEL_32:
      v43 = 1;
      goto LABEL_33;
    }
LABEL_62:
    v42 = -1073741790;
    goto LABEL_32;
  }
  v61 = 0;
  v62 = 0;
  v63 = v26 | DesiredAccess;
  if( v34 )
    v63 = -33554433;
  v64 = (v26 | DesiredAccess) & 0xFDFFFFFF;
  if( !v34 )
    v64 = v26 | DesiredAccess;
  v65 = AccessStatus;
  v66 = v102;
  do
  {
    v67 = (v63 & (*v48 | v26)) == 0;
    v68 = v63 & (*v48 | v26);
    *(_DWORD *)((char *)v65 + (char *)GrantedAccess - (char *)AccessStatus) = v68;
    if( v67 )
    {
      *(_DWORD *)v65 = -1073741790;
      v62 = 1;
    }
    else if( (~v68 & v64) != 0 )
    {
      *(_DWORD *)v65 = -1073741790;
      v62 = 1;
    }
    else
    {
      *(_DWORD *)v65 = 0;
      v61 = 1;
    }
    v48 += 12;
    v65 = (INT64 *)((char *)v65 + 4);
    --v66;
  }
  while( v66 );
  v95 = v62;
  v97 = v61;
  v69 = GrantedAccess;
  if( KeGetCurrentIrql() < 2u && v61 && PrivilegeCount )
  {
    SepAssemblePrivileges(PrivilegeCount, v99, v96, v98, Privileges);
    if( Privileges && !*Privileges )
    {
      v70 = v102;
      v43 = 0;
      v61 = 0;
      v62 = 1;
      v71 = 0;
      if( v102 >= 4 )
      {
        v72 = v102 - 1;
        if( GrantedAccess > (UINT64 *)((char *)AccessStatus + 4 * v72)
          || (char *)GrantedAccess + 4 * v72 < (char *)AccessStatus )
        {
          v73 = v102 & 0xFFFFFFFC;
          do
            v71 += 4;
          while( v71 < (unsigned int)v73 );
          v74 = AccessStatus;
          for( k = (unsigned __int64)(4 * v73) >> 2; k; --k )
          {
            *(_DWORD *)v74 = -1073741801;
            v74 = (INT64 *)((char *)v74 + 4);
          }
          v69 = GrantedAccess;
          memset(GrantedAccess, 0i64, 4 * v73);
          v62 = 1;
          v61 = 0;
          v70 = v102;
        }
      }
      if( v71 < v70 )
      {
        v76 = &v69[v71 / 2];
        v77 = v70 - v71;
        do
        {
          *(_DWORD *)((char *)v76 + (char *)AccessStatus - (char *)v69) = -1073741801;
          *(_DWORD *)v76 = 0;
          v76 = (UINT64 *)((char *)v76 + 4);
          --v77;
        }
        while( v77 );
      }
      goto LABEL_143;
    }
    v62 = v95;
    v61 = v97;
  }
  v43 = 1;
LABEL_143:
  if( ReturnSomeAccessGranted )
    *ReturnSomeAccessGranted = v61;
  if( ReturnSomeAccessDenied )
    *ReturnSomeAccessDenied = v62;
  return v43;
}

Referenced by:

SeAccessCheckByTypeWithAdminlessChecks
SeAccessCheckWithHintWithAdminlessChecks
SepAccessCheckAndAuditAlarmWithAdminlessChecks