RtlpConvertAbsoluteToRelativeSecurityAttribute

NTSTATUS __stdcall RtlpConvertAbsoluteToRelativeSecurityAttribute(
        _CLAIM_SECURITY_ATTRIBUTE_V1 *Attribute,
        _CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 *RelativeAttribute,
        UINT64 *Size){
  ULONG v3; 
  unsigned __int64 v7; 
  ULONG ValueCount; 
  int v9; 
  unsigned int v10; 
  size_t v11; 
  unsigned int v12; 
  USHORT ValueType; 
  ULONG v14; 
  unsigned int v15; 
  unsigned int v16; 
  ULONG v17; 
  unsigned int v18; 
  int v19; 
  unsigned __int64 v20; 
  unsigned int v21; 
  ULONG v22; 
  unsigned int v23; 
  USHORT v24; 
  unsigned int v25; 
  _DWORD *v26; 
  ULONG i; 
  unsigned int v28; 
  PLONG64 pInt64; 
  size_t v30; 
  ULONG j; 
  VOID *v32; 
  int v33; 
  __int64 v34; 
  UINT64 pcbLength; 

  v3 = 0;
  pcbLength = 0i64;
  LODWORD(v7) = 0;
  if( !Attribute || !Size )
    return -1073741811;
  ValueCount = Attribute->ValueCount;
  if( ValueCount )
  {
    v7 = 4i64 * (ValueCount - 1);
    if( v7 > 0xFFFFFFFF )
      return -1073741675;
  }
  v10 = v7 + 20;
  if( (unsigned int)(v7 + 20) < 0x14 )
    return -1073741675;
  v9 = RtlStringCbLengthW(Attribute->Name, 0xFFFFui64, &pcbLength);
  if( v9 < 0 )
    return v9;
  v11 = pcbLength + 2;
  if( (int)pcbLength + 2 < (unsigned int)pcbLength )
    return -1073741675;
  v12 = v11 + v10;
  if( v11 + v10 < v10 )
    return -1073741675;
  ValueType = Attribute->ValueType;
  if( !ValueType )
    goto LABEL_30;
  if( ValueType > 2u )
  {
    if( ValueType == 3 )
    {
      v17 = 0;
      if( Attribute->ValueCount )
      {
        while( 1 )
        {
          v9 = RtlStringCbLengthW((WCHAR *)Attribute->Values.pInt64[v17], 0xFFFFui64, &pcbLength);
          if( v9 < 0 )
            return v9;
          v19 = pcbLength + 2;
          if( (int)pcbLength + 2 < (unsigned int)pcbLength || v19 + v18 < v18 )
            return -1073741675;
          ++v17;
          v12 = v19 + v18;
          if( v17 >= Attribute->ValueCount )
            goto LABEL_30;
        }
      }
      goto LABEL_30;
    }
    if( ValueType == 5 )
    {
LABEL_16:
      v14 = Attribute->ValueCount;
      v15 = 0;
      if( v14 )
      {
        while( 1 )
        {
          v16 = v12 + LODWORD(Attribute->Values.pInt64[2 * v15 + 1]);
          if( v16 < v12 )
            return -1073741675;
          v12 = v16 + 4;
          if( v16 + 4 < v16 )
            return -1073741675;
          if( ++v15 >= v14 )
            goto LABEL_30;
        }
      }
      goto LABEL_30;
    }
    if( ValueType != 6 )
    {
      if( ValueType != 16 )
        goto LABEL_30;
      goto LABEL_16;
    }
  }
  v20 = 8i64 * Attribute->ValueCount;
  if( v20 > 0xFFFFFFFF || (unsigned int)v20 + v12 < v12 )
    return -1073741675;
  v12 += v20;
LABEL_30:
  if( v12 + 3 < v12 )
    return -1073741675;
  v21 = (v12 + 3) & 0xFFFFFFFC;
  v9 = 0;
  if( *(_DWORD *)Size < v21 )
  {
    *(_DWORD *)Size = v21;
    return -1073741789;
  }
  if( !RelativeAttribute )
    return -1073741811;
  *(_DWORD *)Size = v21;
  memset(RelativeAttribute, 0i64, v21);
  RelativeAttribute->ValueType = Attribute->ValueType;
  RelativeAttribute->Reserved = Attribute->Reserved;
  RelativeAttribute->Flags = Attribute->Flags;
  RelativeAttribute->ValueCount = Attribute->ValueCount;
  v22 = Attribute->ValueCount;
  v23 = 4 * v22 + 16;
  if( !v22 )
    v23 = 20;
  RelativeAttribute->Name = v23;
  memmove((char *)RelativeAttribute + v23, Attribute->Name, v11);
  v24 = Attribute->ValueType;
  v25 = v11 + v23;
  v26 = (unsigned int *)((char *)&RelativeAttribute->Name + v25);
  if( !v24 )
    return -1073741811;
  if( v24 <= 2u )
    goto LABEL_51;
  if( v24 != 3 )
  {
    if( v24 == 5 )
      goto LABEL_42;
    if( v24 != 6 )
    {
      if( v24 == 16 )
      {
LABEL_42:
        for( i = 0; i < Attribute->ValueCount; v26 = (unsigned int *)((char *)&RelativeAttribute->Name + v25) )
        {
          RelativeAttribute->Values.pInt64[i] = v25;
          v28 = v25 + 4;
          *v26 = Attribute->Values.pInt64[2 * i + 1];
          pInt64 = Attribute->Values.pInt64;
          v30 = pInt64[2 * i + 1];
          if( v30 )
          {
            memmove((char *)RelativeAttribute + v28, (const VOID *)pInt64[2 * i], v30);
            pInt64 = Attribute->Values.pInt64;
          }
          v25 = LODWORD(pInt64[2 * i++ + 1]) + v28;
        }
        return v9;
      }
      return -1073741811;
    }
LABEL_51:
    if( Attribute->ValueCount )
    {
      do
      {
        v34 = v3++;
        RelativeAttribute->Values.pInt64[v34] = v25;
        v25 += 8;
        *(_QWORD *)v26 = Attribute->Values.pInt64[v34];
        v26 = (unsigned int *)((char *)&RelativeAttribute->Name + v25);
      }
      while( v3 < Attribute->ValueCount );
    }
    return v9;
  }
  for( j = 0; j < Attribute->ValueCount; ++j )
  {
    RelativeAttribute->Values.pInt64[j] = v25;
    v9 = RtlStringCbLengthW((WCHAR *)Attribute->Values.pInt64[j], 0xFFFFui64, &pcbLength);
    if( v9 < 0 )
      break;
    v33 = pcbLength + 2;
    memmove(v32, (const VOID *)Attribute->Values.pInt64[j], pcbLength + 2);
    v25 += v33;
  }
  return v9;
}

Referenced by:

RtlAddResourceAttributeAce