SeCaptureSidAndAttributesArray

NTSTATUS __stdcall SeCaptureSidAndAttributesArray(
        VOID *InputArray,
        UINT64 ArrayCount,
        INT64 RequestorMode,
        VOID *CaptureBuffer,
        UINT64 CaptureBufferLength,
        POOL_TYPE CapturedArray,
        UINT8 AlignedArraySize,
        _SID_AND_ATTRIBUTES **a8,
        UINT64 *a9){
  _SID_AND_ATTRIBUTES *v9; 
  unsigned int v10; 
  VOID **PoolWithTag; 
  NTSTATUS v13; 
  size_t v14; 
  unsigned int v15; 
  unsigned int i; 
  char *v17; 
  unsigned int v18; 
  __int64 v19; 
  VOID *v20; 
  __int64 v21; 
  unsigned int v22; 
  VOID **v23; 
  unsigned int v24; 
  unsigned __int64 v25; 
  unsigned __int64 v26; 
  PVOID *v27; 
  _SID_AND_ATTRIBUTES *v28; 
  char *v29; 
  unsigned int v30; 
  _QWORD *v31; 
  unsigned __int8 *v32; 
  size_t v33; 
  char *v35; 
  unsigned int v36; 
  _QWORD *v37; 
  int v38; 
  _BYTE *v39; 
  int v40; 
  unsigned int v41; 
  int v42; 
  char *v43; 
  VOID **P; 
  char v45; 
  NTSTATUS AlignedArraySizea; 

  v45 = RequestorMode;
  v9 = (_SID_AND_ATTRIBUTES *)CaptureBuffer;
  v10 = ArrayCount;
  PoolWithTag = 0i64;
  P = 0i64;
  v13 = 0;
  AlignedArraySizea = 0;
  if( !(_DWORD)ArrayCount )
  {
    *a8 = 0i64;
    *(_DWORD *)a9 = 0;
    return 0;
  }
  if( (unsigned int)ArrayCount > 0x1000 )
    return -1073741811;
  v14 = 16 * ArrayCount;
  v42 = 16 * ArrayCount + 3;
  v15 = v42 & 0xFFFFFFFC;
  v41 = v42 & 0xFFFFFFFC;
  if( (_BYTE)RequestorMode )
  {
    PoolWithTag = ExAllocatePoolWithTag(1ui64, v15, 1632920915i64);
    P = PoolWithTag;
    if( !PoolWithTag )
      return -1073741670;
    if( v14 )
    {
      if( ((unsigned __int8)InputArray & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      v17 = (char *)InputArray + v14;
      if( (unsigned __int64)v17 > 0x7FFFFFFF0000i64 || v17 < InputArray )
        MEMORY[0x7FFFFFFF0000] = 0;
    }
    v18 = 0;
    v40 = 0;
    while( v18 < v10 )
    {
      v19 = 2i64 * v18;
      v20 = *(VOID **)((char *)InputArray + v19 * 8);
      v21 = (__int64)v20 + 1;
      if( (unsigned __int64)v20 + 1 >= 0x7FFFFFFF0000i64 )
        v21 = 0x7FFFFFFF0000i64;
      v22 = *(unsigned __int8 *)v21;
      if( v22 > 0xF )
      {
        v13 = -1073741704;
        AlignedArraySizea = -1073741704;
        v15 = v41;
        break;
      }
      v23 = &PoolWithTag[v19];
      *v23 = v20;
      v24 = 4 * v22 + 8;
      *((_DWORD *)v23 + 2) = v24;
      v25 = (unsigned __int64)*v23;
      if( ((unsigned __int8)*v23 & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      v26 = v25 + v24;
      if( v26 > 0x7FFFFFFF0000i64 || v26 < v25 )
      {
        MEMORY[0x7FFFFFFF0000] = 0;
        v24 = *((_DWORD *)v23 + 2);
      }
      v15 = ((v24 + 3) & 0xFFFFFFFC) + v41;
      v41 = v15;
      v18 = ++v40;
      v13 = 0;
      AlignedArraySizea = 0;
      PoolWithTag = P;
    }
    if( v13 < 0 )
    {
      ExFreePoolWithTag(PoolWithTag, 0);
      return v13;
    }
    v9 = (_SID_AND_ATTRIBUTES *)CaptureBuffer;
    LOBYTE(RequestorMode) = v45;
  }
  else
  {
    for( i = 0; i < v10; ++i )
      v15 += (4 * *(unsigned __int8 *)(*((_QWORD *)InputArray + 2 * i) + 1i64) + 11) & 0xFFFFFFFC;
  }
  *(_DWORD *)a9 = v15;
  if( !v9 )
  {
    v28 = (_SID_AND_ATTRIBUTES *)ExAllocatePoolWithTag(1ui64, v15, 1632855379i64);
    v27 = (PVOID *)a8;
    *a8 = v28;
    if( v28 )
    {
      LOBYTE(RequestorMode) = v45;
      goto LABEL_32;
    }
    if( v45 )
      ExFreePoolWithTag(P, 0);
    return -1073741670;
  }
  if( v15 <= (unsigned int)CaptureBufferLength )
  {
    v27 = (PVOID *)a8;
    *a8 = v9;
    v28 = v9;
LABEL_32:
    if( (_BYTE)RequestorMode )
    {
      memmove(v28, InputArray, v14);
      v35 = (char *)v28 + (v42 & 0xFFFFFFFC);
      v43 = v35;
      v36 = 0;
      v37 = *v27;
      while( v36 < v10 && !AlignedArraySizea )
      {
        memmove(v35, P[2 * v36], (size_t)P[2 * v36 + 1]);
        v37[2 * v36] = v43;
        v38 = (int)P[2 * v36 + 1];
        v35 = &v43[(v38 + 3) & 0xFFFFFFFC];
        v43 = v35;
        if( (v37[2 * v36 + 1] & 0x1FFFFF80) != 0 )
        {
          AlignedArraySizea = -1073741811;
        }
        else
        {
          v39 = (_BYTE *)v37[2 * v36];
          if( !RtlValidSid(v39) || RtlLengthSid((INT64)v39) != v38 )
            AlignedArraySizea = -1073741704;
          v35 = v43;
        }
        ++v36;
      }
    }
    else
    {
      memmove(v28, InputArray, v14);
      v29 = (char *)v28 + (v42 & 0xFFFFFFFC);
      v30 = 0;
      v31 = *v27;
      while( v30 < v10 )
      {
        v32 = (unsigned __int8 *)v31[2 * v30];
        v33 = 4 * v32[1] + 8;
        memmove(v29, v32, v33);
        v31[2 * v30++] = v29;
        v29 += (v33 + 3) & 0xFFFFFFFC;
      }
      v27 = (PVOID *)a8;
      v9 = (_SID_AND_ATTRIBUTES *)CaptureBuffer;
    }
    if( v45 )
      ExFreePoolWithTag(P, 0);
    if( !v9 && AlignedArraySizea < 0 )
    {
      ExFreePoolWithTag(*v27, 0);
      *v27 = 0i64;
    }
    return AlignedArraySizea;
  }
  if( (_BYTE)RequestorMode )
    ExFreePoolWithTag(PoolWithTag, 0);
  return -1073741789;
}

Referenced by:

NtAdjustGroupsToken
NtCreateLowBoxToken
NtCreateTokenEx
NtFilterToken
NtSetInformationToken
SepCreateClaimAttributes
SepDuplicateClaimAttributes
SepLengthSidAndAttributesArray
SepSetTokenCapabilities