CmLoadAppKey

__int64 __fastcall CmLoadAppKey(
        __int64 *a1,
        const UNICODE_STRING *a2,
        int a3,
        __int64 a4,
        struct _KEVENT *a5,
        POBJECT_HANDLE_INFORMATION a6,
        char a7,
        _QWORD *a8,
        volatile signed __int64 **a9){
  __int16 v9; 
  unsigned __int16 *v12; 
  char v13; 
  volatile signed __int32 *LastHive; 
  unsigned int v15; 
  __int64 v16; 
  __int64 v17; 
  INT64 v19; 
  INT64 v20; 
  _ETHREAD *CurrentThread; 
  int v22; 
  int v23; 
  int v24; 
  NTSTATUS v25; 
  int KeyCommon; 
  NTSTATUS v27; 
  struct _DMA_ADAPTER *v28; 
  _ETHREAD *v29; 
  __int64 v30; 
  const UNICODE_STRING *v31; 
  __int64 **v32; 
  __int64 *v33; 
  struct _EX_RUNDOWN_REF *v34; 
  INT64 v35; 
  unsigned int v36; 
  NTSTATUS v37; 
  volatile signed __int32 *i; 
  __int64 *NextHive; 
  __int64 v40; 
  void *v41; 
  int v42; 
  int v43; 
  INT64 v44; 
  _CM_KEY_CONTROL_BLOCK *v45; 
  _QWORD *v46; 
  _ETHREAD *v47; 
  INT64 v48; 
  INT64 **v49; 
  __int64 *v50; 
  __int64 **v51; 
  __int64 *v52; 
  __int64 **v53; 
  __int64 v54; 
  unsigned __int8 *v55; 
  unsigned __int8 v56; 
  struct _EVENT_DATA_DESCRIPTOR *v57; 
  unsigned int v58; 
  int v59; 
  int v60; 
  int v61; 
  __int64 v62; 
  int v63; 
  int v64; 
  PVOID *Object; 
  PVOID *Objecta; 
  PVOID *Objectb; 
  PVOID *Objectc; 
  char v69; 
  char v70; 
  char v71; 
  char v72; 
  char v73; 
  _FILE_OBJECT *FileObject; 
  int CompareAddress; 
  __int16 v76; 
  __int16 v77; 
  __int16 v78; 
  unsigned __int16 v79; 
  __int16 v80; 
  __int16 v81; 
  HANDLE Handle; 
  INT64 a4a; 
  int v84; 
  int v85; 
  ULONG_PTR v86; 
  PVOID P; 
  int v88; 
  int v89; 
  int v90; 
  int v91; 
  int v92; 
  int v93; 
  int v94; 
  INT64 a6a; 
  INT64 result; 
  INT64 **v97; 
  __int64 *v98; 
  __int64 **v99; 
  const UNICODE_STRING *DmaOperations; 
  char v101; 
  struct _KEVENT Event; 
  KSPIN_LOCK SpinLock; 
  PVOID v104; 
  PVOID v105; 
  _UNICODE_STRING *KeyPath; 
  __int64 v107; 
  volatile signed __int64 **v108; 
  _QWORD *v109; 
  struct _KEVENT *v110; 
  __int64 v111; 
  __int64 v112; 
  __int64 v113; 
  __int64 v114; 
  __int64 v115; 
  __int64 v116; 
  __int64 v117; 
  KAPC_STATE ApcState; 
  struct _EVENT_DATA_DESCRIPTOR v119; 
  __int64 *v120; 
  __int64 v121; 
  int *v122; 
  __int64 v123; 
  __int16 *v124; 
  __int64 v125; 
  __int16 *v126; 
  __int64 v127; 
  __int16 *v128; 
  __int64 v129; 
  INT64 v130; 
  __int64 v131; 
  INT64 v132; 
  int v133; 
  int v134; 
  INT64 v135; 
  __int64 v136; 
  INT64 v137; 
  int v138; 
  int v139; 
  INT64 v140; 
  __int64 v141; 
  INT64 v142; 
  int v143; 
  int v144; 
  __int64 *v145; 
  __int64 v146; 
  struct _EVENT_DATA_DESCRIPTOR v147; 
  int *v148; 
  __int64 v149; 
  unsigned __int16 *v150; 
  __int64 v151; 
  __int16 *v152; 
  __int64 v153; 
  __int16 *v154; 
  __int64 v155; 
  INT64 v156; 
  __int64 v157; 
  __int64 v158; 
  int v159; 
  int v160; 
  INT64 v161; 
  __int64 v162; 
  INT64 v163; 
  int v164; 
  int v165; 
  INT64 v166; 
  __int64 v167; 
  INT64 v168; 
  int v169; 
  int v170; 
  char v171; 
  __int64 *v172; 
  __int64 v173; 
  int *v174; 
  __int64 v175; 
  char *v176; 
  __int64 v177; 
  __int64 *v178; 
  __int64 v179; 
  struct _EVENT_DATA_DESCRIPTOR v180; 
  __int64 *v181; 
  __int64 v182; 
  int *v183; 
  __int64 v184; 
  __int64 *v185; 
  __int64 v186; 
  v9 = a3;
  v110 = a5;
  v109 = a8;
  v92 = a3;
  v108 = a9;
  v111 = a4;
  a6a = (INT64)a6;
  LODWORD(a4a) = 0;
  Handle = 0i64;
  memset((INT64)&result, 0i64);
  v12 = (unsigned __int16 *)a1[2];
  v69 = 0;
  memset(&ApcState, 0, sizeof(ApcState));
  v71 = 0;
  v13 = 0;
  v72 = 0;
  LastHive = 0i64;
  v15 = *v12;
  P = 0i64;
  v107 = 0i64;
  FileObject = 0i64;
  if( (unsigned __int16)v15 >= 2u )
  {
    LODWORD(v16) = v15 >> 1;
    if( v15 >> 1 )
    {
      do
      {
        v17 = a1[2];
        v16 = (unsigned int)(v16 - 1);
        if( *(_WORD *)(*(_QWORD *)(v17 + 8) + 2 * v16) != 92 )
          break;
        *(_WORD *)v17 -= 2;
      }
      while( (_DWORD)v16 );
    }
  }
  if( *(_WORD *)a1[2] < 2u )
    return 3221225485i64;
  CmpAllocateTransientPoolWithTag((_HHIVE *)1, 0x1B0ui64, 0x33394D43ui64, (_CHILD_LIST *)2);
  v20 = v19;
  if( !v19 )
    return 3221225626i64;
  memset(v19, 0i64);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 242);
  if( !ExAcquireRundownProtection((PEX_RUNDOWN_REF)&CmpShutdownRundown) )
  {
    KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
    CmSiFreeMemory((PPRIVILEGE_SET)v20);
    return 3221225865i64;
  }
  v93 = v9 & 0x20;
  v22 = (v93 != 0 ? 119078913 : 51970049) | 0x8000000;
  if( (v9 & 0x80u) == 0 )
    v22 = v93 != 0 ? 119078913 : 51970049;
  v23 = v22 | 0x10000000;
  if( (v9 & 0x200) == 0 )
    v23 = v22;
  v85 = v23;
  v94 = v9 & 0x2000;
  v24 = (v94 != 0) | 0x20;
  if( (v9 & 0x8000) == 0 )
    v24 = (v9 & 0x2000) != 0;
  v84 = v24;
  LODWORD(Object) = 8;
  v25 = CmpOpenHiveFile((_UNICODE_STRING *)a2, 0i64, &Handle, &a4a, (INT64)Object, (INT64)a6, 0i64, 0i64, (INT64)&P);
  KeyCommon = v25;
  if( v25 == -1073741772 )
  {
    v71 = 1;
    DmaOperations = a2;
    v101 = 1;
  }
  else
  {
    if( v25 < 0 )
    {
      LODWORD(Objecta) = 16;
      SetFailureLocation(v20, 0i64, 32i64, (unsigned int)v25, (INT64)Objecta);
      goto LABEL_103;
    }
    v104 = 0i64;
    v27 = ObReferenceObjectByHandle(Handle, 0, *(POBJECT_TYPE *)CmIoFileObjectType, 0, &v104, 0i64);
    v28 = (struct _DMA_ADAPTER *)v104;
    KeyCommon = v27;
    FileObject = (_FILE_OBJECT *)v104;
    ZwClose(Handle);
    if( KeyCommon < 0 )
    {
      LODWORD(Objectb) = 32;
      SetFailureLocation(v20, 0i64, 32i64, (unsigned int)KeyCommon, (INT64)Objectb);
      goto LABEL_101;
    }
    DmaOperations = (const UNICODE_STRING *)v28[2].DmaOperations;
    v101 = 0;
  }
  KeInitializeEvent(&Event, NotificationEvent, 0);
  ExInitializePushLock((EX_RUNDOWN_REF *)&SpinLock);
  v99 = &v98;
  v98 = (__int64 *)&v98;
  v29 = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)v29 + 242);
  ExAcquirePushLockExclusiveEx((UINT64)&CmpAppHiveLoadListLock, 0i64);
  v30 = CmpAppHiveLoadList;
  if( (__int64 *)CmpAppHiveLoadList == &CmpAppHiveLoadList )
  {
LABEL_32:
    if( *(__int64 **)qword_140C47DA8 == &CmpAppHiveLoadList )
    {
      result = (INT64)&CmpAppHiveLoadList;
      v97 = (INT64 **)qword_140C47DA8;
      *(_QWORD *)qword_140C47DA8 = &result;
      qword_140C47DA8 = (__int64)&result;
      ExReleasePushLockEx((UINT64)&CmpAppHiveLoadListLock, 0i64);
      KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
      goto LABEL_34;
    }
    goto LABEL_124;
  }
  v31 = DmaOperations;
  while( 1 )
  {
    if( !*(_BYTE *)(v30 + 40) )
    {
      if( *(const UNICODE_STRING **)(v30 + 32) == v31 )
        break;
      goto LABEL_31;
    }
    if( RtlEqualUnicodeString(*(UNICODE_STRING **)(v30 + 32), (UNICODE_STRING *)a2, 1u) )
      break;
LABEL_31:
    v30 = *(_QWORD *)v30;
    if( (__int64 *)v30 == &CmpAppHiveLoadList )
      goto LABEL_32;
  }
  v32 = *(__int64 ***)(v30 + 24);
  v33 = (__int64 *)(v30 + 16);
  if( *v32 != v33 )
    goto LABEL_124;
  v99 = v32;
  v98 = v33;
  *v32 = (__int64 *)&v98;
  v33[1] = (__int64)&v98;
  v34 = (struct _EX_RUNDOWN_REF *)v99;
  ExAcquireRundownProtection((PEX_RUNDOWN_REF)v99 + 7);
  ExReleasePushLockEx((UINT64)&CmpAppHiveLoadListLock, 0i64);
  KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  KeWaitForSingleObject(&v34[4], Executive, 0, 0, 0i64);
  ExReleaseRundownProtection(v34 + 7);
LABEL_34:
  v35 = a6a;
  v86 = 0i64;
  v70 = 1;
  v36 = CmpCmdHiveOpen(a2, 1, &v70, &v86, v85, v84, a6a, &v69, (void *)v20);
  while( 1 )
  {
    KeyCommon = v36;
    if( !v36 )
    {
      KeyCommon = CmpLoadKeyCommon(v86, a1, v92, v111, 0i64, v110, a7, v108, v70, v69, (_OWORD *)v20);
      goto LABEL_90;
    }
    if( v36 != -1073741757 || v93 || v13 )
    {
      LODWORD(Objectc) = 48;
      SetFailureLocation(v20, 0i64, 32i64, v36, (INT64)Objectc);
      goto LABEL_90;
    }
    if( v71 )
    {
      LODWORD(Objectc) = 8;
      KeyCommon = CmpOpenHiveFile(
                    (_UNICODE_STRING *)a2,
                    0i64,
                    &Handle,
                    &a4a,
                    (INT64)Objectc,
                    v35,
                    0i64,
                    0i64,
                    (INT64)&P);
      if( KeyCommon < 0 )
      {
        LODWORD(Objectc) = 64;
        if( KeyCommon == -1073741772 )
          KeyCommon = -1073741757;
LABEL_77:
        v44 = (unsigned int)KeyCommon;
LABEL_78:
        SetFailureLocation(v20, 0i64, 32i64, v44, (INT64)Objectc);
        goto LABEL_90;
      }
      v105 = 0i64;
      v37 = ObReferenceObjectByHandle(Handle, 0, *(POBJECT_TYPE *)CmIoFileObjectType, 0, &v105, 0i64);
      v28 = (struct _DMA_ADAPTER *)v105;
      KeyCommon = v37;
      FileObject = (_FILE_OBJECT *)v105;
      ZwClose(Handle);
      if( KeyCommon < 0 )
      {
        LODWORD(Objectc) = 80;
        SetFailureLocation(v20, 0i64, 32i64, (unsigned int)KeyCommon, (INT64)Objectc);
        goto LABEL_91;
      }
      v35 = a6a;
    }
    LOCK_HIVE_LOAD();
    CmpLockRegistryFreezeAware(1u);
    LastHive = (volatile signed __int32 *)CmpGetLastHive();
    if( LastHive )
      break;
LABEL_73:
    CmpUnlockRegistry();
    UNLOCK_HIVE_LOAD();
    v70 = 1;
    v69 = 0;
    v86 = 0i64;
    v36 = CmpCmdHiveOpen(a2, 1, &v70, &v86, v85, v84, v35, &v69, (void *)v20);
    v13 = 1;
  }
LABEL_44:
  for( CompareAddress = CmpActiveAppHiveUnloadCount; CompareAddress; CompareAddress = CmpActiveAppHiveUnloadCount )
  {
    CmpUnlockRegistry();
    UNLOCK_HIVE_LOAD();
    ExBlockOnAddressPushLock(&CmpActiveAppHiveUnloadEvent, &CmpActiveAppHiveUnloadCount, &CompareAddress, 4ui64, 0i64);
    LOCK_HIVE_LOAD();
    CmpLockRegistryFreezeAware(1u);
  }
  for( i = 0i64; ; i = (volatile signed __int32 *)v40 )
  {
    NextHive = CmpGetNextHive(i);
    v40 = (__int64)NextHive;
    if( !NextHive )
      break;
    HIDWORD(a4a) = *((_DWORD *)NextHive + 1202);
    if( HIDWORD(a4a) )
    {
      CmpUnlockRegistry();
      UNLOCK_HIVE_LOAD();
      ExBlockOnAddressPushLock(
        (_EX_PUSH_LOCK *)(v40 + 4816),
        (volatile VOID *)(v40 + 4808),
        (char *)&a4a + 4,
        4ui64,
        0i64);
      LOCK_HIVE_LOAD();
      CmpLockRegistryFreezeAware(1u);
      if( _InterlockedExchangeAdd((volatile signed __int32 *)(v40 + 4272), 0xFFFFFFFF) == 1 )
        CmpDeleteHive((PVOID)v40);
      if( (volatile signed __int32 *)v40 == LastHive )
        break;
      goto LABEL_44;
    }
    v41 = (void *)NextHive[192];
    if( v41 && CmpIsThisSameFile(FileObject, v41) )
    {
      v42 = *(_DWORD *)(v40 + 4152);
      v43 = *(_DWORD *)(v40 + 160) & 0x8000;
      if( (v42 & 0x20) == 0 || (v42 & 0x40) != 0 )
      {
        CmpUnlockRegistry();
        UNLOCK_HIVE_LOAD();
        if( _InterlockedExchangeAdd((volatile signed __int32 *)(v40 + 4272), 0xFFFFFFFF) == 1 )
          CmpDeleteHive((PVOID)v40);
        v44 = 3221225539i64;
        LODWORD(Objectc) = 96;
        KeyCommon = -1073741757;
        goto LABEL_78;
      }
      if( v94 )
      {
        if( !v43 && !CmpCheckHivePrimaryFileReadWriteAccess(P) )
        {
          CmpUnlockRegistry();
          UNLOCK_HIVE_LOAD();
          if( _InterlockedExchangeAdd((volatile signed __int32 *)(v40 + 4272), 0xFFFFFFFF) == 1 )
            CmpDeleteHive((PVOID)v40);
          KeyCommon = -1073741790;
          LODWORD(Objectc) = 128;
          goto LABEL_77;
        }
      }
      else if( v43 )
      {
        CmpUnlockRegistry();
        UNLOCK_HIVE_LOAD();
        if( _InterlockedExchangeAdd((volatile signed __int32 *)(v40 + 4272), 0xFFFFFFFF) == 1 )
          CmpDeleteHive((PVOID)v40);
        v44 = 3221225539i64;
        LODWORD(Objectc) = 112;
        KeyCommon = -1073741757;
        goto LABEL_78;
      }
      CmpAttachToRegistryProcess(&ApcState);
      v45 = *(_CM_KEY_CONTROL_BLOCK **)(v40 + 2928);
      v107 = v40;
      KeyPath = 0i64;
      CmpConstructNameWithStatus(v45, &KeyPath);
      v46 = v109;
      *v109 = KeyPath;
      CmpDetachFromRegistryProcess(&ApcState);
      if( !*v46 )
      {
        CmpUnlockRegistry();
        UNLOCK_HIVE_LOAD();
        KeyCommon = -1073741670;
        if( _InterlockedExchangeAdd((volatile signed __int32 *)(v40 + 4272), 0xFFFFFFFF) == 1 )
          CmpDeleteHive((PVOID)v40);
        goto LABEL_90;
      }
      CmpReferenceKeyControlBlockUnsafe(*(volatile INT64 **)(v40 + 2928));
      *v108 = *(volatile signed __int64 **)(v40 + 2928);
      CmpUnlockRegistry();
      UNLOCK_HIVE_LOAD();
      KeyCommon = 0;
LABEL_69:
      if( _InterlockedExchangeAdd((volatile signed __int32 *)(v40 + 4272), 0xFFFFFFFF) == 1 )
        CmpDeleteHive((PVOID)v40);
      break;
    }
    if( (volatile signed __int32 *)v40 == LastHive )
      goto LABEL_69;
  }
  if( !v107 )
  {
    v35 = a6a;
    goto LABEL_73;
  }
  v72 = 1;
LABEL_90:
  v28 = (struct _DMA_ADAPTER *)FileObject;
LABEL_91:
  v47 = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)v47 + 242);
  ExAcquirePushLockExclusiveEx((UINT64)&CmpAppHiveLoadListLock, 0i64);
  v48 = result;
  v49 = v97;
  if( *(INT64 **)(result + 8) != &result || *v97 != &result )
    goto LABEL_124;
  *v97 = (INT64 *)result;
  *(_QWORD *)(v48 + 8) = v49;
  v50 = v98;
  if( v98 == (__int64 *)&v98 )
    goto LABEL_98;
  v51 = v99;
  v52 = v98 - 2;
  if( (__int64 **)v98[1] != &v98
    || *v99 != (__int64 *)&v98
    || (*v99 = v98,
        v50[1] = (__int64)v51,
        v53 = (__int64 **)qword_140C47DA8,
        *(__int64 **)qword_140C47DA8 != &CmpAppHiveLoadList) )
  {
LABEL_124:
    __fastfail(3u);
  }
  *v52 = (__int64)&CmpAppHiveLoadList;
  v52[1] = (__int64)v53;
  *v53 = v52;
  qword_140C47DA8 = (__int64)v52;
LABEL_98:
  ExReleasePushLockEx((UINT64)&CmpAppHiveLoadListLock, 0i64);
  KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  KeSetEvent(&Event, 0);
  ExWaitForRundownProtectionRelease((EX_RUNDOWN_REF *)&SpinLock);
  if( LastHive && _InterlockedExchangeAdd(LastHive + 1068, 0xFFFFFFFF) == 1 )
    CmpDeleteHive((PVOID)LastHive);
LABEL_101:
  if( v28 )
    HalPutDmaAdapter(v28);
LABEL_103:
  if( P )
    ExFreePoolWithTag(P, 0);
  ExReleaseRundownProtection((PEX_RUNDOWN_REF)&CmpShutdownRundown);
  KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  if( KeyCommon >= 0 )
  {
    if( (unsigned int)dword_140C02130 > 5 && tlgKeywordOn((__int64)&dword_140C02130, 0x400000000008i64) )
    {
      v173 = 8i64;
      v116 = 1i64;
      v172 = &v116;
      v55 = (unsigned __int8 *)&unk_1400220C0;
      v91 = KeyCommon;
      v174 = &v91;
      v56 = 6;
      v73 = v72;
      v176 = &v73;
      v178 = &v117;
      v57 = (struct _EVENT_DATA_DESCRIPTOR *)&v171;
      v175 = 4i64;
      v177 = 1i64;
      v117 = 0x1000000i64;
      v179 = 8i64;
LABEL_122:
      tlgWriteAgg((__int64)&dword_140C02130, v55, v54, v56, v57);
    }
  }
  else if( *(_WORD *)(v20 + 8) || *(_WORD *)(v20 + 10) || *(_BYTE *)(v20 + 394) )
  {
    if( (unsigned int)dword_140C02130 > 5 )
    {
      if( tlgKeywordOn((__int64)&dword_140C02130, 0x400000000008i64) )
      {
        v114 = 1i64;
        v121 = 8i64;
        v60 = *(unsigned __int16 *)(v20 + 10);
        v61 = *(unsigned __int8 *)(v20 + 394);
        v120 = &v114;
        v62 = v20 + 12;
        v78 = v61;
        v122 = &v89;
        v124 = &v76;
        v126 = &v77;
        v128 = &v78;
        v137 = v20 + 108;
        v138 = 12 * v60;
        v142 = v20 + 396;
        v145 = &v115;
        v77 = v60;
        v133 = 12 * v59;
        v135 = v20 + 10;
        v89 = KeyCommon;
        v123 = 4i64;
        v76 = v59;
        v125 = 2i64;
        v127 = 2i64;
        v129 = 2i64;
        v130 = v20 + 8;
        v131 = 2i64;
        v132 = v20 + 12;
        v134 = 0;
        v136 = 2i64;
        v139 = 0;
        v140 = v20 + 394;
        v141 = 2i64;
        v143 = 8 * v61;
        v144 = 0;
        v115 = 0x1000000i64;
        v146 = 8i64;
        tlgWriteAgg((__int64)&dword_140C02130, (unsigned __int8 *)&byte_140022183, v20 + 394, 0xEu, &v119);
        v58 = dword_140C02130;
      }
      else
      {
        v62 = v20 + 12;
      }
      if( v58 > 5 && tlgKeywordOn((__int64)&dword_140C02130, 8i64) )
      {
        v90 = KeyCommon;
        v148 = &v90;
        v79 = *(_WORD *)(v20 + 8);
        v150 = &v79;
        v63 = *(unsigned __int16 *)(v20 + 10);
        v152 = &v80;
        v64 = *(unsigned __int8 *)(v20 + 394);
        v159 = 12 * v79;
        v163 = v20 + 108;
        v164 = 12 * v63;
        v81 = v64;
        v168 = v20 + 396;
        v80 = v63;
        v161 = v20 + 10;
        v166 = v20 + 394;
        v169 = 8 * v64;
        v149 = 4i64;
        v151 = 2i64;
        v153 = 2i64;
        v154 = &v81;
        v155 = 2i64;
        v156 = v20 + 8;
        v157 = 2i64;
        v158 = v62;
        v160 = 0;
        v162 = 2i64;
        v165 = 0;
        v167 = 2i64;
        v170 = 0;
        tlgWriteTransfer_EtwWriteTransfer(
          (__int64)&dword_140C02130,
          (unsigned __int8 *)&dword_140021F84,
          0i64,
          0i64,
          0xCu,
          &v147);
      }
    }
  }
  else if( (unsigned int)dword_140C02130 > 5 && tlgKeywordOn((__int64)&dword_140C02130, 0x400000000008i64) )
  {
    v112 = 1i64;
    v181 = &v112;
    v55 = (unsigned __int8 *)word_14002212A;
    v182 = 8i64;
    v183 = &v88;
    v56 = 5;
    v88 = KeyCommon;
    v185 = &v113;
    v57 = &v180;
    v184 = 4i64;
    v113 = 0x1000000i64;
    v186 = 8i64;
    goto LABEL_122;
  }
  CmSiFreeMemory((PPRIVILEGE_SET)v20);
  return(unsigned int)KeyCommon;
}

Referenced by:

CmLoadDifferencingKey