CmpGetSymbolicLinkTarget

INT64 __fastcall CmpGetSymbolicLinkTarget(
        INT64 a1,
        INT64 a2,
        INT16 a3,
        INT16 a4,
        INT64 a5,
        INT64 a6,
        INT64 a7,
        INT64 a8,
        INT64 a9){
  unsigned int v11; 
  unsigned int v12; 
  _CM_KEY_CONTROL_BLOCK *v13; 
  char v14; 
  INT16 v15; 
  char v16; 
  INT64 KcbAtLayerHeight; 
  INT64 v18; 
  char v19; 
  unsigned __int64 v20; 
  char v21; 
  unsigned int v22; 
  unsigned int i; 
  unsigned __int16 *v24; 
  int v25; 
  const _UNICODE_STRING *v26; 
  unsigned __int64 v27; 
  _UNICODE_STRING *v28; 
  void *v29; 
  int NameInListWithStatus; 
  wchar_t *Buffer; 
  UINT64 v33; 
  INT64 v34; 
  INT16 v35; 
  UINT64 v36; 
  __int64 v37; 
  __int64 v38; 
  __int64 v39; 
  __int64 v40; 
  unsigned int v41; 
  unsigned int v42; 
  unsigned __int16 *ComponentNameAtIndex; 
  int v44; 
  unsigned int v45; 
  __int64 v46; 
  void(__fastcall *v47)(__int64, __int64 *); 
  INT64 v48; 
  _UNICODE_STRING v49; 
  unsigned __int16 v50; 
  _WORD *v51; 
  __int16 v52; 
  __int16 v53; 
  unsigned int v54; 
  unsigned __int8 *v55; 
  int v56; 
  __int64 v57; 
  int v58; 
  unsigned int v59; 
  _CM_KEY_VALUE *v60; 
  unsigned int v61; 
  unsigned int v62; 
  const _UNICODE_STRING *v63; 
  unsigned __int64 v64; 
  __int64 v65; 
  void *v66; 
  __int16 v67; 
  __int16 v68; 
  unsigned __int8 v69[4]; 
  unsigned int DestinationString; 
  _UNICODE_STRING DestinationString_8; 
  __int16 v72[2]; 
  __int16 v73; 
  INT16 v74; 
  unsigned int v75[3]; 
  PVOID BugCheckParameter2; 
  PVOID P; 
  UINT64 v78; 
  __int64 v79; 
  INT64 v80; 
  __int64 v81[2]; 
  __m128i v82; 
  INT64 v83; 
  __int64 v84; 
  _UNICODE_STRING SourceString; 
  UNICODE_STRING SourceName; 
  INT64 v87; 
  _QWORD *v88; 
  __int64 v89; 
  INT64 a2a; 
  INT64 v91[2]; 
  __int128 v92; 
  INT64 v93[22]; 

  v78 = a6;
  a2a = a7;
  v87 = a8;
  v88 = (_QWORD *)a9;
  v11 = a4;
  v83 = a1;
  v72[0] = 0;
  v73 = 0;
  v74 = a4;
  v12 = a3;
  v89 = a5;
  DestinationString_8 = 0i64;
  SourceString = 0i64;
  SourceName = 0i64;
  RtlInitUnicodeString(&DestinationString_8, 0i64);
  DestinationString = -1;
  v13 = 0i64;
  v14 = 0;
  BugCheckParameter2 = 0i64;
  v84 = 0i64;
  P = 0i64;
  memset(v75, 0, sizeof(v75));
  v68 = 0;
  v79 = 0xFFFFFFFFi64;
  v81[0] = 0xFFFFFFFFi64;
  v69[0] = 0;
  v80 = 0xFFFFFFFFi64;
  memset(v93, 0i64, 0xA8u);
  v15 = *(_WORD *)(a1 + 2);
  *(_OWORD *)v91 = 0i64;
  WORD1(v91[0]) = -1;
  v92 = 0i64;
  if( a5 || v15 )
  {
    v16 = 0;
  }
  else
  {
    v16 = 1;
    v15 = 0;
  }
  KcbAtLayerHeight = CmpGetKcbAtLayerHeight(a1, v15);
  v18 = KcbAtLayerHeight;
  if( !v16 || (*(_DWORD *)(KcbAtLayerHeight + 8) & 8) == 0 )
  {
LABEL_30:
    v33 = v78;
    if( (*(_DWORD *)(v78 + 160) & 1) == 0 )
    {
      CmpAttachToRegistryProcess((KAPC_STATE *)(v78 + 168));
      *(_DWORD *)(v33 + 160) |= 1u;
    }
    v34 = v83;
    v35 = *(_WORD *)(v83 + 2);
    v67 = v35;
    if( v35 < 0 )
      goto LABEL_111;
    while( 1 )
    {
      v78 = CmpGetKcbAtLayerHeight(v34, v35);
      v36 = v78;
      if( (unsigned int)CmpGetEffectiveKcbSemantics(v78) == 1 )
        goto LABEL_111;
      if( *(_DWORD *)(v37 + 40) != -1 )
      {
        if( CmEqualTrans(*(_QWORD *)(v37 + 288), v89) )
        {
          if( !*(_DWORD *)(v36 + 280) )
          {
            DestinationString = -1;
            goto LABEL_95;
          }
          NameInListWithStatus = CmpFindNameInListWithStatus(
                                   *(_HHIVE **)(v36 + 32),
                                   (_CHILD_LIST *)(v36 + 280),
                                   &CmSymbolicLinkValueName,
                                   0,
                                   0i64,
                                   &DestinationString);
        }
        else
        {
          v38 = (*(__int64(__fastcall **)(_QWORD, _QWORD, __int64 *))(*(_QWORD *)(v36 + 32) + 8i64))(
                  *(_QWORD *)(v36 + 32),
                  *(unsigned int *)(v36 + 40),
                  &v79);
          NameInListWithStatus = CmpFindNameInListWithStatus(
                                   *(_HHIVE **)(v36 + 32),
                                   (_CHILD_LIST *)(v38 + 36),
                                   &CmSymbolicLinkValueName,
                                   0,
                                   0i64,
                                   &DestinationString);
          (*(void(__fastcall **)(_QWORD, __int64 *))(*(_QWORD *)(v78 + 32) + 16i64))(*(_QWORD *)(v78 + 32), &v79);
        }
        if( NameInListWithStatus >= 0 )
        {
          v39 = *(_QWORD *)(v78 + 32);
          *(_QWORD *)&v75[1] = v39;
          goto LABEL_39;
        }
        if( NameInListWithStatus != -1073741772 )
          goto LABEL_99;
      }
LABEL_95:
      v35 = --v67;
      if( v67 < 0 )
      {
        v39 = *(_QWORD *)&v75[1];
LABEL_39:
        if( DestinationString != -1 )
        {
          v40 = (*(__int64(__fastcall **)(__int64, _QWORD, __int64 *))(v39 + 8))(v39, DestinationString, v81);
          v84 = v40;
          if( (*(_BYTE *)(v40 + 16) & 2) == 0 && *(_DWORD *)(v40 + 12) == 6 )
          {
            if( !CmpGetValueData(
                    *(_HHIVE **)&v75[1],
                    DestinationString,
                    (_CM_KEY_VALUE *)v40,
                    v75,
                    &P,
                    v69,
                    (_HV_GET_CELL_CONTEXT *)&v80) )
            {
              NameInListWithStatus = -1073741670;
              goto LABEL_99;
            }
            if( v75[0] <= 0xFFFF && (v75[0] & 1) == 0 )
            {
              v41 = v12;
              SourceString.Buffer = (wchar_t *)P;
              SourceString.Length = v75[0];
              SourceString.MaximumLength = v75[0];
              v42 = LOWORD(v75[0]);
              LODWORD(v78) = v12;
              if( v12 < v74 )
              {
                do
                {
                  ComponentNameAtIndex = (unsigned __int16 *)CmpGetComponentNameAtIndex(a2, v41);
                  v41 = v44 + 1;
                  v42 += *ComponentNameAtIndex + 2;
                }
                while( v41 < v45 );
              }
              if( v42 <= 0xFFFF )
              {
                DestinationString_8.Buffer = (wchar_t *)ExAllocatePoolWithTag(1ui64, v42, 909528387i64);
                Buffer = DestinationString_8.Buffer;
                if( !DestinationString_8.Buffer )
                {
                  NameInListWithStatus = -1073741670;
                  v21 = 1;
                  goto LABEL_21;
                }
                DestinationString_8.Length = 0;
                DestinationString_8.MaximumLength = v42;
                RtlUnicodeStringCopy(&DestinationString_8, &SourceString);
                if( v69[0] )
                {
                  ExFreePoolWithTag(P, 0);
                  v46 = *(_QWORD *)&v75[1];
                }
                else
                {
                  v46 = *(_QWORD *)&v75[1];
                  (*(void(__fastcall **)(_QWORD, INT64 *))(*(_QWORD *)&v75[1] + 16i64))(*(_QWORD *)&v75[1], &v80);
                }
                v47 = *(void(__fastcall **)(__int64, __int64 *))(v46 + 16);
                P = 0i64;
                v47(v46, v81);
                v84 = 0i64;
                v48 = v83;
                CmpUnlockKcbStack(v83);
                v49 = DestinationString_8;
                if( v16 )
                {
                  v21 = 0;
                  SourceName.Buffer = DestinationString_8.Buffer;
                  v50 = 0;
                  v82 = (__m128i)DestinationString_8;
                  SourceName.Length = 0;
                  SourceName.MaximumLength = DestinationString_8.MaximumLength;
                  if( DestinationString_8.Length )
                  {
                    v51 = (_WORD *)v82.m128i_i64[1];
                    v52 = v82.m128i_i16[1];
                    v53 = v82.m128i_i16[0];
                    while( *v51 == 92 )
                    {
                      ++v51;
                      v53 -= 2;
                      v52 -= 2;
                      v82.m128i_i64[1] = (__int64)v51;
                      v50 += 2;
                      v82.m128i_i16[0] = v53;
                      v82.m128i_i16[1] = v52;
                      SourceName.Length = v50;
                      if( !v53 )
                        goto LABEL_61;
                    }
                    if( v53 )
                    {
                      while( *v51 != 92 )
                      {
                        ++v51;
                        v53 -= 2;
                        v52 -= 2;
                        v82.m128i_i64[1] = (__int64)v51;
                        v50 += 2;
                        v82.m128i_i16[0] = v53;
                        v82.m128i_i16[1] = v52;
                        SourceName.Length = v50;
                        if( !v53 )
                          goto LABEL_61;
                      }
                      do
                      {
                        if( *v51 != 92 )
                          break;
                        ++v51;
                        v52 -= 2;
                        v53 -= 2;
                      }
                      while( v53 );
                      v82.m128i_i64[1] = (__int64)v51;
                      v82.m128i_i16[0] = v53;
                      v82.m128i_i16[1] = v52;
                    }
                  }
LABEL_61:
                  if( !CmpCompareUnicodeString(&SourceName, &CmRegistryRootName, 2ui64)
                    && (int)CmpComputeComponentHashes(&v82, v72, (INT64)v93) >= 0 )
                  {
                    v54 = v72[0];
                    if( (int)CmpValidateComponents((unsigned int)v72[0], (INT64)v93) >= 0 )
                    {
                      if( (int)CmpPerformCompleteKcbCacheLookup(
                                  *((_QWORD *)CmpRegistryRootObject + 1),
                                  0i64,
                                  v54,
                                  (INT64)v93,
                                  0i64,
                                  (INT64 *)&BugCheckParameter2,
                                  (CHAR *)&v68 + 1,
                                  &v73) < 0 )
                      {
                        v13 = (_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2;
                      }
                      else if( v73 == (_WORD)v54 )
                      {
                        v13 = (_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2;
                        if( (int)CmpStartKcbStackForTopLayerKcb((INT64)v91, (INT64)BugCheckParameter2) >= 0 )
                        {
                          CmpLockKcbStackShared((INT64)v91);
                          v56 = CmpConstructAndCacheName(v13, 0i64, v55);
                          CmpUnlockKcbStack((INT64)v91);
                          if( v56 >= 0 )
                          {
                            if( HIBYTE(v68) )
                            {
                              CmpUnlockHashEntryByKcb((INT64)v13);
                              HIBYTE(v68) = 0;
                            }
                            CmpLockKcbStackTopExclusiveRestShared(v48);
                            v21 = 1;
                            if( !CmpIsKeyStackDeleted(v48, 0i64) )
                            {
                              v57 = (*(__int64(__fastcall **)(_QWORD, _QWORD, __int64 *))(*(_QWORD *)(v18 + 32) + 8i64))(
                                      *(_QWORD *)(v18 + 32),
                                      *(unsigned int *)(v18 + 40),
                                      &v79);
                              v58 = CmpFindNameInListWithStatus(
                                      *(_HHIVE **)(v18 + 32),
                                      (_CHILD_LIST *)(v57 + 36),
                                      &CmSymbolicLinkValueName,
                                      0,
                                      0i64,
                                      &DestinationString);
                              (*(void(__fastcall **)(_QWORD, __int64 *))(*(_QWORD *)(v18 + 32) + 16i64))(
                                *(_QWORD *)(v18 + 32),
                                &v79);
                              if( v58 >= 0 )
                              {
                                v59 = DestinationString;
                                *(_QWORD *)&v75[1] = *(_QWORD *)(v18 + 32);
                                v60 = (_CM_KEY_VALUE *)(*(__int64(__fastcall **)(_QWORD, _QWORD, __int64 *))(*(_QWORD *)&v75[1] + 8i64))(
                                                         *(_QWORD *)&v75[1],
                                                         DestinationString,
                                                         v81);
                                v84 = (__int64)v60;
                                if( v60->Type == 6
                                  && CmpGetValueData(
                                       *(_HHIVE **)&v75[1],
                                       v59,
                                       v60,
                                       v75,
                                       &P,
                                       v69,
                                       (_HV_GET_CELL_CONTEXT *)&v80)
                                  && v75[0] <= 0xFFFF
                                  && (v75[0] & 1) == 0 )
                                {
                                  SourceString.Length = v75[0];
                                  SourceString.MaximumLength = v75[0];
                                  SourceString.Buffer = (wchar_t *)P;
                                  if( !CmpCompareUnicodeString(&DestinationString_8, &SourceString, 0i64) )
                                  {
                                    CmpCleanUpKcbCachedSymlink(v18, a2a);
                                    *(_QWORD *)(v18 + 104) = v13;
                                    CmpReferenceKeyControlBlockUnsafe((volatile INT64 *)v13);
                                    *(_WORD *)(v18 + 8) |= 8u;
                                    CmpUnlockKcbStack(v48);
                                    goto LABEL_78;
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                      else
                      {
                        CmpDereferenceKeyControlBlock((UINT64)BugCheckParameter2);
                        v13 = 0i64;
                      }
                    }
                  }
                }
                else
                {
LABEL_78:
                  v21 = 0;
                }
                v61 = v74;
                v62 = v78;
                if( (unsigned int)v78 < v74 )
                {
                  do
                  {
                    v63 = (const _UNICODE_STRING *)CmpGetComponentNameAtIndex(a2, v62);
                    v64 = (unsigned __int64)DestinationString_8.Length >> 1;
                    DestinationString_8.Length += 2;
                    DestinationString_8.Buffer[v64] = 92;
                    RtlUnicodeStringCat(&DestinationString_8, v63);
                    ++v62;
                  }
                  while( v62 < v61 );
                  v49 = DestinationString_8;
                  v14 = v68;
                }
                v65 = v87;
                v66 = *(void **)(v87 + 8);
                if( v66 )
                {
                  ExFreePoolWithTag(v66, 0);
                  *(_QWORD *)(v65 + 8) = 0i64;
                }
                if( HIBYTE(v68) )
                  CmpUnlockHashEntryByKcb((INT64)v13);
                *v88 = v13;
                v13 = 0i64;
                *(_UNICODE_STRING *)v65 = v49;
                RtlInitUnicodeString(&DestinationString_8, 0i64);
                NameInListWithStatus = 0;
                goto LABEL_19;
              }
            }
          }
        }
LABEL_111:
        NameInListWithStatus = -1073741772;
LABEL_99:
        v21 = 1;
LABEL_19:
        Buffer = DestinationString_8.Buffer;
        if( DestinationString_8.Buffer )
          ExFreePoolWithTag(DestinationString_8.Buffer, 0);
LABEL_21:
        if( P )
        {
          if( v69[0] )
            ExFreePoolWithTag(P, 0);
          else(*(void(__fastcall **)(_QWORD, INT64 *))(*(_QWORD *)&v75[1] + 16i64))(*(_QWORD *)&v75[1], &v80);
        }
        if( v84 )
          (*(void(__fastcall **)(_QWORD, __int64 *))(*(_QWORD *)&v75[1] + 16i64))(*(_QWORD *)&v75[1], v81);
        if( Buffer )
          ExFreePoolWithTag(Buffer, 0);
        if( v21 )
          CmpUnlockKcbStack(v83);
        goto LABEL_28;
      }
      v34 = v83;
    }
  }
  v19 = 0;
  BugCheckParameter2 = *(PVOID *)(KcbAtLayerHeight + 104);
  v20 = *((_QWORD *)BugCheckParameter2 + 37);
  if( (v20 & 1) != 0 )
  {
    v19 = 1;
    v20 &= ~1ui64;
  }
  if( !v20 || v19 )
  {
    v13 = (_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2;
    v14 = 0;
    goto LABEL_30;
  }
  v13 = (_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2;
  CmpReferenceKeyControlBlockUnsafe((volatile INT64 *)BugCheckParameter2);
  CmpUnlockKcbStack(v83);
  v21 = 0;
  CmpLockKcbShared(v13);
  v22 = *(unsigned __int16 *)v20;
  for( i = v12; i < v11; v22 += *v24 + 2 )
  {
    v24 = (unsigned __int16 *)CmpGetComponentNameAtIndex(a2, i);
    i = v25 + 1;
  }
  if( v22 > 0xFFFF )
  {
    v14 = 1;
    NameInListWithStatus = -1073741772;
    goto LABEL_19;
  }
  DestinationString_8.Buffer = (wchar_t *)ExAllocatePoolWithTag(1ui64, v22, 909528387i64);
  if( DestinationString_8.Buffer )
  {
    DestinationString_8.MaximumLength = v22;
    DestinationString_8.Length = 0;
    RtlUnicodeStringCopy(&DestinationString_8, (const _UNICODE_STRING *)v20);
    for( ; v12 < v11; ++v12 )
    {
      v26 = (const _UNICODE_STRING *)CmpGetComponentNameAtIndex(a2, v12);
      v27 = (unsigned __int64)DestinationString_8.Length >> 1;
      DestinationString_8.Length += 2;
      DestinationString_8.Buffer[v27] = 92;
      RtlUnicodeStringCat(&DestinationString_8, v26);
    }
    v28 = (_UNICODE_STRING *)v87;
    v29 = *(void **)(v87 + 8);
    if( v29 )
      ExFreePoolWithTag(v29, 0);
    *v28 = DestinationString_8;
    RtlInitUnicodeString(&DestinationString_8, 0i64);
    CmpUnlockKcb(v13);
    v14 = 0;
    *v88 = v13;
    v13 = 0i64;
    NameInListWithStatus = 0;
    goto LABEL_19;
  }
  v14 = 1;
  NameInListWithStatus = -1073741670;
LABEL_28:
  if( v13 )
  {
    if( v14 )
      CmpUnlockKcb(v13);
    CmpDereferenceKeyControlBlock((UINT64)v13);
  }
  CmpCleanupKcbStack((INT64)v91);
  CmpCleanupPathInfo((INT64)v93);
  return(unsigned int)NameInListWithStatus;
}

Referenced by:

CmpDoParseKey