CmpWalkOneLevel
INT64 __fastcall CmpWalkOneLevel(
INT64 a1,
INT64 a2,
INT64 *a3,
INT64 a4,
_BOOL *a5,
const _UNICODE_STRING *SearchName,
INT64 ComponentHash,
UINT64 PathHash,
INT64 a9,
CHAR a10,
INT64 a11){
INT64 v11;
_WORD *v14;
INT16 v15;
__int16 v16;
__int64 v17;
__int64 v18;
_EX_PUSH_LOCK *v19;
signed __int32 v20;
signed __int32 v21;
__int16 v22;
__int16 i;
__int64 v24;
__int64 v25;
__int64 v26;
_EPROCESS *Process;
__int16 v28;
_CM_KEY_CONTROL_BLOCK *v29;
__int64 KeyCell;
__int64 v31;
_HHIVE *KeyHive;
__int64 v33;
INT64 v34;
int v35;
__int64 v36;
unsigned int v37;
__int64 v38;
__int16 v39;
__int16 v40;
UINT64 v41;
bool v42;
__int16 v43;
__int64 v44;
__int64 v45;
__int64 v46;
unsigned __int64 v47;
_CM_KEY_INDEX *v49;
int v50;
__int16 v51;
UINT16 *v52;
__int64 v53;
UINT16 v54;
unsigned __int16 v55;
int v56;
volatile INT64 *v57;
int v58;
__int16 v59;
__int16 v60;
int v61;
__int64 v62;
LIST_ENTRY *v63;
int v64;
INT64 KcbAtLayerHeight;
_CMHIVE *v66;
_CM_KEY_CONTROL_BLOCK *KcbInHashEntryByName;
INT64 v68;
INT64 v69;
_CM_KEY_NODE *v70;
UINT64 v71;
_HHIVE *v72;
_EX_PUSH_LOCK *v73;
__int16 v74;
int SubKeyInLeafWithStatus;
__int16 v76;
__int16 v77;
UINT Index;
PVOID v79;
int v80[2];
__int64 v81;
_CM_KEY_CONTROL_BLOCK *ParentKcb;
int v83;
int v84;
INT64 v85;
int v86;
__int64 v87;
_CM_KEY_CONTROL_BLOCK *ResultKcb;
LIST_ENTRY *ListIterator;
__m128i v90;
v11 = a1;
v81 = 0i64;
v14 = 0i64;
v15 = *(_WORD *)(a1 + 66) - 1;
ResultKcb = 0i64;
LODWORD(v81) = -1;
v74 = -1;
v79 = 0i64;
if( v15 >= 0 )
{
do
{
KcbAtLayerHeight = CmpGetKcbAtLayerHeight(a2, v15);
CmpLockHashEntryShared(*(_QWORD *)(KcbAtLayerHeight + 32), (unsigned int)PathHash);
v66 = *(_CMHIVE **)(KcbAtLayerHeight + 32);
KcbInHashEntryByName = CmpFindKcbInHashEntryByName(
v66,
(_CM_PATH_HASH)PathHash,
(_CM_KEY_CONTROL_BLOCK *)KcbAtLayerHeight,
SearchName);
v79 = KcbInHashEntryByName;
if( KcbInHashEntryByName )
{
v14 = KcbInHashEntryByName;
CmpReferenceKeyControlBlockLockNotHeld(KcbInHashEntryByName);
CmpUnlockHashEntry(*(_QWORD *)(KcbAtLayerHeight + 32), (unsigned int)PathHash);
CmpPopulateKcbStack(a4, (__int64)v14);
v16 = v14[33] + 1;
goto LABEL_3;
}
CmpUnlockHashEntry((INT64)v66, (unsigned int)PathHash);
--v15;
}
while( v15 >= 0 );
v14 = v79;
}
v16 = 0;
*(_WORD *)(a4 + 2) = -1;
LABEL_3:
v77 = v16;
if( v16 <= *(__int16 *)(v11 + 66) )
{
do
{
if( v16 >= 2 )
v17 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v16 - 16);
else
v17 = *(_QWORD *)(a2 + 8i64 * v16 + 8);
v18 = *(_QWORD *)(v17 + 32);
v19 = (_EX_PUSH_LOCK *)(*(_QWORD *)(v18 + 1640)
+ 24
* (((101027 * ((unsigned int)PathHash ^ ((unsigned int)PathHash >> 9))) ^ ((unsigned __int64)(101027 * ((unsigned int)PathHash ^ ((unsigned int)PathHash >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v18 + 1648) - 1)));
ExAcquirePushLockExclusiveEx(v19, 0i64);
v19[1]._bf_0 = (__int64)KeGetCurrentThread();
_m_prefetchw((const void *)(v18 + 4272));
v20 = *(_DWORD *)(v18 + 4272);
if( !v20 )
LABEL_136:
KeBugCheckEx(0x51u, (PVOID)0x17, (PVOID)v18, (PVOID)0xC, (PVOID)(unsigned int)PathHash);
while( 1 )
{
v21 = v20;
v20 = _InterlockedCompareExchange((volatile signed __int32 *)(v18 + 4272), v20 + 1, v20);
if( v21 == v20 )
break;
if( !v20 )
goto LABEL_136;
}
v74 = v16++;
}
while( v16 <= *(__int16 *)(v11 + 66) );
v14 = v79;
}
v22 = *(_WORD *)(a2 + 2);
for( i = 0; i <= v22; ++i )
{
if( i >= 2 )
v24 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * i - 16);
else
v24 = *(_QWORD *)(a2 + 8i64 * i + 8);
ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)(v24 + 48), 0i64);
_InterlockedIncrement((volatile signed __int32 *)(v24 + 56));
v22 = *(_WORD *)(a2 + 2);
}
ListIterator = 0i64;
if( v22 < 0 )
goto LABEL_121;
while( 1 )
{
if( v22 >= 2 )
v25 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v22 - 16);
else
v25 = *(_QWORD *)(a2 + 8i64 * v22 + 8);
if( *(_WORD *)(v25 + 66) && *(_BYTE *)(v25 + 65) == 1 )
goto LABEL_121;
if( *(_DWORD *)(v25 + 40) != -1 )
break;
if( --v22 < 0 )
goto LABEL_121;
}
if( a9 )
{
LODWORD(v62) = CmListGetNextElement((LIST_ENTRY *)(*(_QWORD *)(a2 + 8) + 208i64), &ListIterator, 32i64);
if( v62 )
{
do
{
v64 = *(_DWORD *)(v62 + 68);
if( v64 == 2 || v64 == 11 )
break;
LODWORD(v62) = CmListGetNextElement(v63 + 13, &ListIterator, 32i64);
}
while( v62 );
if( CmEqualTrans(*(_QWORD *)(v62 + 56), a9) )
{
LABEL_121:
v68 = 328192i64;
LABEL_122:
v35 = -1073741772;
SubKeyInLeafWithStatus = -1073741772;
v69 = 3221225524i64;
goto LABEL_123;
}
}
}
v26 = *(_QWORD *)(v11 + 240);
if( v26 && !CmEqualTrans(a9, v26) )
{
v68 = 328448i64;
goto LABEL_122;
}
if( (*(_DWORD *)(v11 + 184) & 0x20000) != 0 )
{
v68 = 328704i64;
goto LABEL_122;
}
if( (*(_DWORD *)(a11 + 160) & 1) == 0 )
{
Process = (_EPROCESS *)*(&CmpDummyThreadEvent + 5);
if( !*(&CmpDummyThreadEvent + 5) )
Process = KeGetCurrentThread()->ApcState.Process;
KiStackAttachProcess(Process, 0i64, (_KAPC_STATE *)(a11 + 168));
*(_DWORD *)(a11 + 160) |= 1u;
}
if( v14 )
v28 = v14[33] + 1;
else
v28 = 0;
v76 = v28;
if( v28 > *(__int16 *)(v11 + 66) )
{
LABEL_98:
v79 = 0i64;
SubKeyInLeafWithStatus = 0;
v60 = v74 - 1;
if( !a10 )
v60 = v74;
v39 = v60;
*a5 = a10 != 0;
*a3 = (INT64)v14;
v35 = 0;
goto LABEL_46;
}
while( 2 )
{
if( v28 >= 2 )
v29 = *(_CM_KEY_CONTROL_BLOCK **)(*(_QWORD *)(a2 + 24) + 8i64 * v28 - 16);
else
v29 = *(_CM_KEY_CONTROL_BLOCK **)(a2 + 8i64 * v28 + 8);
KeyCell = v29->KeyHash.KeyCell;
ParentKcb = v29;
if( (_DWORD)KeyCell == -1 )
{
v37 = -1;
goto LABEL_41;
}
v31 = (__int64)v29->KeyHash.KeyHive->GetCellRoutine(v29->KeyHash.KeyHive, KeyCell, (_HV_GET_CELL_CONTEXT *)&v81);
KeyHive = v29->KeyHash.KeyHive;
v33 = v31;
v87 = v31;
if( (KeyHive->HiveFlags & 0x8001) == 0 && (*(_BYTE *)(v31 + 12) & (unsigned __int8)CmpAccessBitForPhase) == 0 )
{
KeyHive->ReleaseCellRoutine(KeyHive, (_HV_GET_CELL_CONTEXT *)&v81);
ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)&v29->KeyHash.KeyHive->FlusherLock, 0i64);
v70 = (_CM_KEY_NODE *)v29->KeyHash.KeyHive->GetCellRoutine(
v29->KeyHash.KeyHive,
v29->KeyHash.KeyCell,
(_HV_GET_CELL_CONTEXT *)&v81);
v71 = v29->KeyHash.KeyCell;
v72 = v29->KeyHash.KeyHive;
v33 = (__int64)v70;
v87 = (__int64)v70;
CmpUpdateKeyNodeAccessBits(v72, v70, v71);
v73 = (_EX_PUSH_LOCK *)v29->KeyHash.KeyHive;
if( _InterlockedCompareExchange64(&v73[9]._bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(v73 + 9);
KeAbPostRelease(&v73[9]);
}
v34 = (INT64)v29->KeyHash.KeyHive;
v80[1] = 0;
v85 = v34;
v84 = -1;
v35 = -1073741772;
v36 = 0i64;
v83 = 0;
SubKeyInLeafWithStatus = -1073741772;
v80[0] = -1;
Index = 0;
v86 = 0;
if( !*(_DWORD *)(v34 + 208) )
goto LABEL_38;
while( !*(_DWORD *)(v33 + 4 * v36 + 20) )
{
LABEL_36:
v36 = (unsigned int)(v83 + 1);
v83 = v36;
if( (unsigned int)v36 >= *(_DWORD *)(v34 + 208) )
goto LABEL_37;
}
v49 = (_CM_KEY_INDEX *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(v34 + 8))(
v34,
*(unsigned int *)(v33 + 4 * v36 + 28),
v80);
if( !v49 )
goto LABEL_145;
if( v49->Signature == 26994 )
{
if( (int)CmpFindSubKeyInRoot((_HHIVE *)v34, v49, SearchName, 0i64) < 0 )
{
v35 = -1073741670;
goto LABEL_85;
}
(*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v80);
if( Index == -1 )
goto LABEL_80;
v49 = (_CM_KEY_INDEX *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(v34 + 8))(v34, Index, v80);
if( !v49 )
{
LABEL_145:
v35 = -1073741670;
SubKeyInLeafWithStatus = -1073741670;
goto LABEL_37;
}
}
if( v49->Signature != 26732 )
{
SubKeyInLeafWithStatus = CmpFindSubKeyInLeafWithStatus((_HHIVE *)v34, v49, SearchName, 0i64, &Index);
v35 = SubKeyInLeafWithStatus;
if( (int)(SubKeyInLeafWithStatus + 0x80000000) >= 0 && SubKeyInLeafWithStatus != -1073741772 )
goto LABEL_86;
v56 = Index;
LABEL_83:
if( v56 != -1 )
{
v84 = v56;
v35 = 0;
goto LABEL_85;
}
goto LABEL_79;
}
v50 = 0;
v51 = _mm_cvtsi128_si32(*(__m128i *)SearchName);
v90 = *(__m128i *)SearchName;
if( v51 )
{
v52 = (UINT16 *)v90.m128i_i64[1];
v53 = (unsigned __int16)(((unsigned __int16)(v51 - 1) >> 1) + 1);
do
{
v54 = *v52;
if( *v52 >= 0x61u )
{
if( v54 > 0x7Au )
v54 = NLS_UPCASE(v54);
else
v54 -= 32;
}
++v52;
v50 = v54 + 37 * v50;
--v53;
}
while( v53 );
v90.m128i_i64[1] = (__int64)v52;
}
v55 = 0;
Index = -1;
if( !v49->Count )
{
LABEL_78:
v34 = v85;
v35 = -1073741772;
SubKeyInLeafWithStatus = -1073741772;
LABEL_79:
(*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v80);
LABEL_80:
v33 = v87;
goto LABEL_36;
}
while( 1 )
{
if( v50 != *(_DWORD *)&v49[v55 + 1].Signature )
goto LABEL_77;
v61 = CmpDoCompareKeyName(v85, SearchName, 0i64, v49[v55].List[0]);
if( v61 == 2 )
break;
if( !v61 )
{
v56 = v49[v55].List[0];
v34 = v85;
v35 = 0;
SubKeyInLeafWithStatus = 0;
Index = v56;
goto LABEL_83;
}
LABEL_77:
if( ++v55 >= v49->Count )
goto LABEL_78;
}
v34 = v85;
v35 = -1073741670;
LABEL_85:
SubKeyInLeafWithStatus = v35;
LABEL_86:
(*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v80);
LABEL_37:
v11 = a1;
LABEL_38:
ParentKcb->KeyHash.KeyHive->ReleaseCellRoutine(ParentKcb->KeyHash.KeyHive, (_HV_GET_CELL_CONTEXT *)&v81);
if( v35 == -1073741772 )
{
v37 = -1;
goto LABEL_40;
}
if( v35 < 0 )
{
CmpRecordParseFailure(a11, 328960i64, (unsigned int)v35);
goto LABEL_45;
}
v37 = v84;
if( v84 != -1 )
{
v29 = ParentKcb;
goto LABEL_90;
}
LABEL_40:
v29 = ParentKcb;
LABEL_41:
if( *(_WORD *)(v11 + 66) || a10 )
{
LABEL_90:
v57 = (volatile INT64 *)v79;
v58 = CmpCreateKeyControlBlock(
(_CMHIVE *)v29->KeyHash.KeyHive,
v37,
v29,
(_CM_KEY_CONTROL_BLOCK *)v79,
0,
(_UNICODE_STRING *)SearchName,
(_CM_COMPONENT_HASH)ComponentHash,
(_CM_PATH_HASH)PathHash,
&ResultKcb);
SubKeyInLeafWithStatus = v58;
v35 = v58;
if( v58 >= 0 )
{
if( v57 )
CmpDereferenceKeyControlBlockUnsafe(v57);
v14 = ResultKcb;
ResultKcb = 0i64;
v79 = v14;
++*(_WORD *)(a4 + 2);
if( v76 >= 2 )
*(_QWORD *)(*(_QWORD *)(a4 + 24) + 8i64 * v76 - 16) = v14;
else
*(_QWORD *)(a4 + 8i64 * v76 + 8) = v14;
v59 = *(_WORD *)(v11 + 66);
if( v76 != v59 )
{
CmpUnlockHashEntry((INT64)ParentKcb->KeyHash.KeyHive, (unsigned int)PathHash);
++v77;
v59 = *(_WORD *)(v11 + 66);
}
v28 = v76 + 1;
v76 = v28;
if( v28 > v59 )
goto LABEL_98;
continue;
}
v69 = (unsigned int)v58;
v68 = 329472i64;
LABEL_123:
CmpRecordParseFailure(a11, v68, v69);
goto LABEL_45;
}
break;
}
v35 = -1073741772;
SubKeyInLeafWithStatus = -1073741772;
v38 = *(unsigned __int8 *)(a11 + 258);
if( (unsigned __int8)v38 < 4u )
{
*(_DWORD *)(a11 + 8 * v38 + 260) = -1073741772;
*(_DWORD *)(a11 + 8i64 * (unsigned __int8)(*(_BYTE *)(a11 + 258))++ + 264) = 329216;
}
LABEL_45:
v39 = v74;
LABEL_46:
v40 = 0;
if( *(__int16 *)(a2 + 2) >= 0 )
{
do
{
if( v40 >= 2 )
v41 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v40 - 16);
else
v41 = *(_QWORD *)(a2 + 8i64 * v40 + 8);
v42 = (*(_DWORD *)(v41 + 8) & 0x80000) != 0;
if( *(struct _KTHREAD **)(v41 + 56) == KeGetCurrentThread() )
*(_QWORD *)(v41 + 56) = 0i64;
else
_InterlockedDecrement((volatile signed __int32 *)(v41 + 56));
ExReleasePushLockEx(v41 + 48, 0);
if( v42 && (*(_DWORD *)(v41 + 8) & 0x80000) != 0 )
CmpFreeKeyControlBlock(v41);
++v40;
}
while( v40 <= *(__int16 *)(a2 + 2) );
v35 = SubKeyInLeafWithStatus;
}
v43 = v77;
if( v77 <= v39 )
{
v44 = 8i64 * v77 - 16;
do
{
if( v43 >= 2 )
v45 = *(_QWORD *)(v44 + *(_QWORD *)(a2 + 24));
else
v45 = *(_QWORD *)(v44 + a2 + 24);
v46 = *(_QWORD *)(v45 + 32);
v47 = *(_QWORD *)(v46 + 1640)
+ 24
* (((101027 * ((unsigned int)PathHash ^ ((unsigned int)PathHash >> 9))) ^ ((unsigned __int64)(101027 * ((unsigned int)PathHash ^ ((unsigned int)PathHash >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v46 + 1648) - 1));
*(_QWORD *)(v47 + 8) = 0i64;
ExReleasePushLockEx(v47, 0);
if( _InterlockedExchangeAdd((volatile signed __int32 *)(v46 + 4272), 0xFFFFFFFF) == 1 )
CmpDeleteHive((PVOID)v46);
++v43;
v44 += 8i64;
}
while( v43 <= v39 );
v35 = SubKeyInLeafWithStatus;
}
if( v79 )
CmpDereferenceKeyControlBlock((UINT64)v79);
return(unsigned int)v35;
}Referenced by:
CmpDoBuildVirtualStack
CmpDoParseKey