CmQueryKey

INT64 __fastcall CmQueryKey(
        _CM_KEY_BODY *KeyBody,
        _CM_KEY_BODY *VirtualKeyBody,
        _KEY_INFORMATION_CLASS KeyInformationClass,
        VOID *KeyInformation,
        UINT64 Length,
        UINT64 *ResultLength){
  _CM_TRANS *v10; 
  _CM_KEY_CONTROL_BLOCK *KeyControlBlock; 
  _CM_KEY_CONTROL_BLOCK *v12; 
  int KeyData; 
  struct _UNICODE_STRING *p_UnicodeString; 
  unsigned int v15; 
  UINT8 *v16; 
  unsigned int v17; 
  _CM_KEY_CONTROL_BLOCK *v18; 
  INT64 v19; 
  int v20; 
  int v21; 
  int v22; 
  unsigned int v23; 
  int v24; 
  _ETHREAD *CurrentThread; 
  _EPROCESS *CurrentThreadProcess; 
  int v27; 
  INT64 v28; 
  bool v29; 
  unsigned int v30; 
  unsigned int v31; 
  int v32; 
  unsigned int v33; 
  int v34; 
  _LARGE_INTEGER KcbLastWriteTime; 
  NTSTATUS v37; 
  unsigned int LayeredKey; 
  _DWORD v39[3]; 
  INT64 a9; 
  UINT8 *v41; 
  PVOID P; 
  _CM_TRANS *CmTrans[2]; 
  int v44; 
  int a7; 
  VOID *v46; 
  UINT64 *v47; 
  struct _UNICODE_STRING UnicodeString; 
  INT64 v49; 
  _CM_KEY_BODY *v50; 
  INT64 a5[2]; 
  INT64 v52; 
  INT64 a6; 
  struct _SECURITY_SUBJECT_CONTEXT SubjectContext; 
  INT64 v55[2]; 
  __int128 v56; 
  __int128 v57; 
  KAPC_STATE ApcState; 
  v41 = (UINT8 *)KeyInformation;
  CmTrans[1] = (_CM_TRANS *)KeyBody;
  v50 = KeyBody;
  *(_QWORD *)&v39[1] = VirtualKeyBody;
  v46 = KeyInformation;
  v47 = ResultLength;
  P = 0i64;
  v10 = 0i64;
  CmTrans[0] = 0i64;
  UnicodeString = 0i64;
  memset(&ApcState, 0, sizeof(ApcState));
  *(_OWORD *)a5 = 0i64;
  CmpInitializeDelayDerefContext(a5);
  CmpAttachToRegistryProcess(&ApcState);
  CmpLockRegistry();
  KeyControlBlock = KeyBody->KeyControlBlock;
  v49 = (INT64)KeyControlBlock;
  if( KeyControlBlock->LayerHeight )
  {
    LayeredKey = CmQueryLayeredKey(
                   (__int64)KeyBody,
                   KeyInformationClass,
                   (unsigned int *)KeyInformation,
                   Length,
                   (unsigned int *)ResultLength);
    CmpUnlockRegistry();
    CmpDetachFromRegistryProcess(&ApcState);
    return LayeredKey;
  }
  else
  {
    if( !*(_QWORD *)&KeyBody->Trans.0 && !KeyBody->KtmUow )
    {
LABEL_4:
      if( VirtualKeyBody )
      {
        KeyControlBlock = VirtualKeyBody->KeyControlBlock;
        v49 = (INT64)KeyControlBlock;
      }
      if( VirtualKeyBody )
        CmpLockTwoKcbsShared(VirtualKeyBody->KeyControlBlock, KeyBody->KeyControlBlock);
      else
        CmpLockKcbShared(KeyBody->KeyControlBlock);
      if( KeyInformationClass != KeyNameInformation )
      {
        if( VirtualKeyBody && CmpIsKeyDeletedForKeyBody((__int64)VirtualKeyBody, (__int64)v10)
          || CmpIsKeyDeletedForKeyBody((__int64)KeyBody, (__int64)v10) )
        {
          v24 = -1073741444;
          if( (*((_BYTE *)KeyBody + 48) & 1) != 0 )
            v24 = -1073740763;
          KeyData = v24;
          goto LABEL_104;
        }
        switch( KeyInformationClass )
        {
          case KeyFlagsInformation:
            *(_DWORD *)ResultLength = 12;
            if( (unsigned int)Length < 0xC )
            {
              KeyData = -1073741789;
            }
            else
            {
              *(_DWORD *)KeyInformation = CmGetKeyFlags((INT64)KeyControlBlock, (INT64)v10, v19);
              *((_DWORD *)KeyInformation + 1) = 0;
              v20 = 0;
              if( (KeyControlBlock->KeyHash.KeyCell & 0x80000000) != 0 )
              {
                v20 = 1;
                *((_DWORD *)KeyInformation + 1) = 1;
              }
              v21 = *((_DWORD *)KeyControlBlock + 46);
              if( (v21 & 0x100000) != 0 )
              {
                *((_DWORD *)KeyInformation + 1) = v20 | 2;
                v21 = *((_DWORD *)KeyControlBlock + 46);
              }
              *((_DWORD *)KeyInformation + 2) = (unsigned __int8)v21 >> 4;
              KeyData = 0;
            }
            v16 = v41;
            break;
          case KeyVirtualizationInformation:
            memset(&SubjectContext, 0, sizeof(SubjectContext));
            CurrentThread = (_ETHREAD *)KeGetCurrentThread();
            CurrentThreadProcess = (_EPROCESS *)PsGetCurrentThreadProcess();
            SeCaptureSubjectContextEx(CurrentThread, CurrentThreadProcess, &SubjectContext);
            v27 = 4;
            *(_DWORD *)ResultLength = 4;
            if( (unsigned int)Length >= 4 )
            {
              v28 = v49;
              v29 = KCBNeedsVirtualImage_0(v49);
              v16 = v41;
              v30 = v29 | *(_DWORD *)v41 & 0xFFFFFFFE;
              *(_DWORD *)v41 = v30;
              v31 = v30 & 0xFFFFFFFD;
              *(_DWORD *)v16 = v31;
              v32 = v31;
              if( v29 && (*(_DWORD *)(v28 + 184) & 0x20) == 0 )
              {
                v32 = v31 | 2;
                *(_DWORD *)v16 = v31 | 2;
              }
              if( !CmpVEEnabled || (*(_DWORD *)(v28 + 184) & 0x1000000) == 0 )
                v27 = 0;
              v33 = v27 | v32 & 0xFFFFFFFB;
              *(_DWORD *)v16 = v33;
              v34 = v33 ^ ((unsigned __int8)v33 ^ (unsigned __int8)(*(_DWORD *)(v28 + 184) >> 22)) & 8;
              *(_DWORD *)v16 = v34;
              *(_DWORD *)v16 = v34 ^ ((unsigned __int8)v34 ^ (unsigned __int8)(*(_DWORD *)(v28 + 184) >> 19)) & 0x10;
              KeyData = 0;
            }
            else
            {
              KeyData = -1073741789;
              v16 = v41;
            }
            SeReleaseSubjectContext(&SubjectContext);
            v10 = CmTrans[0];
            break;
          case MaxKeyInfoClass:
            *(_DWORD *)ResultLength = 4;
            if( (unsigned int)Length >= 4 )
            {
              v22 = *(_DWORD *)KeyInformation;
              if( (KeyControlBlock->KeyHash.KeyHive[2].Storage[1].FreeDisplay[6].RealVectorSize & 1) != 0 )
                v23 = v22 & 0xFFFFFFFE;
              else
                v23 = v22 | 1;
              *(_DWORD *)KeyInformation = v23;
              KeyData = 0;
              v16 = v41;
LABEL_25:
              if( VirtualKeyBody )
              {
                if( ((KeyInformationClass - 3) & 0xFFFFFFFC) != 0 || KeyInformationClass == KeyCachedInformation )
                {
                  KcbLastWriteTime = VirtualKeyBody->KeyControlBlock->KcbLastWriteTime;
                  if( KeyBody->KeyControlBlock->KcbLastWriteTime.QuadPart < KcbLastWriteTime.QuadPart )
                    *(_LARGE_INTEGER *)v16 = KcbLastWriteTime;
                }
                if( ((KeyInformationClass - 2) & 0xFFFFFFFD) == 0 )
                {
                  v39[0] = 0;
                  v52 = 0i64;
                  v44 = 0;
                  *(_OWORD *)v55 = 0i64;
                  v56 = 0i64;
                  v57 = 0i64;
                  if( (unsigned int)CmpFindSubKeyByNumberFromMergedView(
                                       (INT64)VirtualKeyBody->KeyControlBlock,
                                       (INT64)KeyBody->KeyControlBlock,
                                       0xFFFFFFFFi64,
                                       (INT64)v10,
                                       (INT64)a5,
                                       (INT64)&v52,
                                       (INT64)&v44,
                                       0i64,
                                       (INT64)v39) == -2147483622 )
                  {
                    if( KeyInformationClass == KeyFullInformation )
                      *((_DWORD *)v16 + 5) = v39[0];
                    else
                      *((_DWORD *)v16 + 3) = v39[0];
                  }
                  if( (unsigned int)CmEnumerateValueKeyFromMergedView(
                                       (__int64)KeyBody,
                                       (__int64)VirtualKeyBody,
                                       1,
                                       0xFFFFFFFF,
                                       0,
                                       0i64,
                                       0,
                                       0i64,
                                       (__int64)v39) == -2147483622 )
                  {
                    if( KeyInformationClass == KeyFullInformation )
                      *((_DWORD *)v16 + 8) = v39[0];
                    else
                      *((_DWORD *)v16 + 5) = v39[0];
                  }
                  KeyData = CmpQueryKeyData(
                              (INT64)KeyBody->KeyControlBlock,
                              (unsigned int)KeyInformationClass,
                              (INT64)v55,
                              0x30ui64,
                              ResultLength,
                              (INT64)v10);
                  if( (int)(KeyData + 0x80000000) < 0 || KeyData == -2147483643 )
                  {
                    if( KeyInformationClass == KeyFullInformation )
                    {
                      if( DWORD2(v56) > *((_DWORD *)v16 + 6) )
                        *((_DWORD *)v16 + 6) = DWORD2(v56);
                      if( DWORD1(v57) > *((_DWORD *)v16 + 9) )
                        *((_DWORD *)v16 + 9) = DWORD1(v57);
                      if( DWORD2(v57) > *((_DWORD *)v16 + 10) )
                        *((_DWORD *)v16 + 10) = DWORD2(v57);
                    }
                    else
                    {
                      if( (unsigned int)v56 > *((_DWORD *)v16 + 4) )
                        *((_DWORD *)v16 + 4) = v56;
                      if( DWORD2(v56) > *((_DWORD *)v16 + 6) )
                        *((_DWORD *)v16 + 6) = DWORD2(v56);
                      if( HIDWORD(v56) > *((_DWORD *)v16 + 7) )
                        *((_DWORD *)v16 + 7) = HIDWORD(v56);
                    }
                  }
                }
              }
              else if( CmpVEEnabled )
              {
                v18 = KeyBody->KeyControlBlock;
                if( (*((_DWORD *)v18 + 46) & 0x1000000) != 0 && ((KeyInformationClass - 2) & 0xFFFFFFFD) == 0 )
                {
                  LODWORD(a9) = 0;
                  a6 = 0i64;
                  a7 = 0;
                  KeyData = CmpFindSubKeyByNumberFromMergedView(
                              (INT64)v18,
                              0i64,
                              0xFFFFFFFFi64,
                              (INT64)v10,
                              (INT64)a5,
                              (INT64)&a6,
                              (INT64)&a7,
                              0i64,
                              (INT64)&a9);
                  if( KeyData == -2147483622 )
                  {
                    if( KeyInformationClass == KeyFullInformation )
                      *((_DWORD *)v16 + 5) = a9;
                    else
                      *((_DWORD *)v16 + 3) = a9;
                    KeyData = 0;
                  }
                }
              }
              goto LABEL_104;
            }
            KeyData = -1073741789;
LABEL_104:
            if( VirtualKeyBody )
              CmpUnlockTwoKcbs(VirtualKeyBody->KeyControlBlock, v50->KeyControlBlock);
            else
              CmpUnlockKcb((UINT64)v50->KeyControlBlock);
            CmpDrainDelayDerefContext((UINT64 **)a5);
            CmpUnlockRegistry();
            CmpDetachFromRegistryProcess(&ApcState);
            if( UnicodeString.Buffer )
            {
              RtlFreeAnsiString(&UnicodeString);
            }
            else if( P )
            {
              CmpFreeTransientPoolWithTag(P, 0x624E4D43ui64);
            }
            return(unsigned int)KeyData;
          default:
            KeyData = CmpQueryKeyData(
                        (INT64)KeyControlBlock,
                        (unsigned int)KeyInformationClass,
                        (INT64)KeyInformation,
                        (unsigned int)Length,
                        ResultLength,
                        (INT64)v10);
            v16 = v41;
            break;
        }
LABEL_24:
        if( KeyData >= 0 )
          goto LABEL_25;
        goto LABEL_104;
      }
      v12 = KeyBody->KeyControlBlock;
      if( CmpIsKeyDeletedForKeyBody((__int64)KeyBody, (__int64)v10) )
      {
        if( (*((_DWORD *)KeyBody + 12) & 1) != 0 )
        {
          KeyData = -1073740763;
          goto LABEL_104;
        }
        KeyData = -1073741444;
      }
      else
      {
        KeyData = 0;
      }
      if( !v12->NameBlock )
      {
LABEL_58:
        KeyData = -1073741670;
        goto LABEL_104;
      }
      if( CmpVEEnabled && (*((_DWORD *)v12 + 46) & 0x1000000) != 0 )
      {
        if( CmVirtualKCBToRealPath(v12, &UnicodeString) < 0 )
        {
LABEL_16:
          if( P )
          {
            v15 = *(unsigned __int16 *)P;
            *(_DWORD *)ResultLength = v15 + 4;
            v16 = v41;
            if( (unsigned int)Length < 4 )
            {
              KeyData = -1073741789;
            }
            else
            {
              *(_DWORD *)v41 = v15;
              v17 = Length - 4;
              if( (int)Length - 4 < v15 )
                KeyData = -2147483643;
              if( v17 >= v15 )
                v17 = v15;
              memmove(v16 + 4, *((UINT8 **)P + 1), v17);
            }
            goto LABEL_24;
          }
          goto LABEL_58;
        }
        p_UnicodeString = &UnicodeString;
      }
      else
      {
        p_UnicodeString = CmpConstructName(v12);
      }
      P = p_UnicodeString;
      goto LABEL_16;
    }
    CmpLockKcbShared(KeyControlBlock);
    if( CmpIsKeyDeletedForKeyBody((__int64)KeyBody, 0i64) )
    {
      KeyData = -1073740763;
      if( (*((_DWORD *)KeyBody + 12) & 1) == 0 )
        KeyData = -1073741444;
      CmpUnlockKcb((UINT64)KeyControlBlock);
      CmpUnlockRegistry();
      CmpDetachFromRegistryProcess(&ApcState);
      return(unsigned int)KeyData;
    }
    CmpUnlockKcb((UINT64)KeyControlBlock);
    v37 = CmpTransSearchAddTransFromKeyBody(KeyBody, CmTrans);
    if( v37 >= 0 )
    {
      v10 = CmTrans[0];
      goto LABEL_4;
    }
    CmpUnlockRegistry();
    CmpDetachFromRegistryProcess(&ApcState);
    return(unsigned int)v37;
  }
}

Referenced by:

NtQueryKey