MiCompletePrivateZeroFault
INT64 __fastcall MiCompletePrivateZeroFault(INT64 rcx0, INT64 rdx0, UINT64 a3){
UINT64 v3;
_QWORD *v4;
__int64 v5;
INT64 v6;
unsigned __int64 PteBase;
_QWORD *v9;
UINT64 v10;
int v11;
__int64 v12;
INT64 v13;
__int64 v14;
int v15;
__int64 v16;
int v17;
__int64 v18;
unsigned int v19;
unsigned __int64 v20;
unsigned __int64 LeafVa;
int v22;
unsigned __int64 v23;
unsigned __int64 v24;
int v25;
unsigned __int64 v26;
_MMPTE *PxeUserLimit;
unsigned __int64 v28;
_MMPFN *PfnDb;
UINT64 v30;
__int64 v31;
__int64 v32;
_MMPTE *Pml4eBase;
__int64 v34;
volatile signed __int64 *v35;
__int64 v36;
INT64 v37;
volatile signed __int64 v38;
signed __int64 v39;
signed __int64 v40;
INT64 v41;
bool v42;
__int64 v43;
void *v44;
WCHAR *v45;
int v46;
unsigned __int64 v47;
int v48;
INT64 v49;
__int64 v50;
unsigned __int64 v51;
unsigned int v52;
UINT64 v53;
unsigned __int64 v54;
char *v55;
_ETHREAD *CurrentThread;
unsigned int v57;
unsigned int v58;
char v59;
unsigned __int8 v60;
int v61;
unsigned __int8 v62;
INT64 v63;
UINT64 v64;
char v65;
unsigned __int64 v66;
_MMPTE *v67;
INT64 v68;
RTL_BALANCED_NODE *Address;
__int64 v70;
UNICODE_STRING *v71;
int v72;
__int16 v73;
int v74;
char v75;
__int16 v76;
UNICODE_STRING *v77;
int v78;
char v79;
__int64 v80;
int v81;
__int64 v82;
_MMPFN *v83;
unsigned int v84;
unsigned int v85;
unsigned __int64 v86;
_MMPTE *v87;
UINT64 v88;
INT64 v89;
INT64 v90;
INT64 v91;
char *v92;
__int64 v93;
_QWORD *v94;
INT64 a5;
__int64 a6;
INT64 a7;
INT64 v99;
INT64 a9;
INT64 v101;
INT64 a11;
INT64 a12;
UINT64 SpinCount;
UINT64 v105;
UINT64 v106;
unsigned __int64 v107;
UINT64 v108;
unsigned __int64 v109;
UINT64 a1;
UINT64 v111;
_QWORD *v112;
unsigned __int64 v113;
RTL_BALANCED_NODE *v114;
INT64 v115;
__int64 v116;
unsigned __int64 v117;
unsigned __int64 v118;
unsigned __int64 v119;
__int64 v120;
INT64 v122;
unsigned int v124;
v3 = a3;
v4 = *(_QWORD **)(rcx0 + 56);
v5 = *(_QWORD *)(rcx0 + 16) >> 9;
v6 = rcx0;
v112 = v4;
PteBase = (unsigned __int64)MmGetPteBase();
v9 = *(_QWORD **)(rcx0 + 8);
v10 = PteBase + (v5 & 0x7FFFFFFFF8i64);
v111 = v10;
LODWORD(a9) = 0;
v11 = 0;
v116 = v9[7];
v12 = v9[2];
if( (v12 & 1) != 0 )
{
if( *(_BYTE *)(v12 & 0xFFFFFFFFFFFFFFFEui64) == 3 )
v11 = 1;
LODWORD(a9) = v11;
}
v13 = (INT64)v4;
if( (*(_DWORD *)v6 & 8) == 0 )
v13 = 0i64;
v115 = v13;
v101 = *((_QWORD *)KeGetCurrentThread() + 23);
v14 = *(_QWORD *)(v6 + 64);
v113 = PteBase + ((*v9 >> 9) & 0x7FFFFFFFF8i64);
v15 = 16;
v114 = (RTL_BALANCED_NODE *)v14;
HIDWORD(a9) = 0;
if( v14 )
{
v16 = *(unsigned int *)(v14 + 52);
LODWORD(v16) = v16 & 0x7FFFFFFF;
if( (v16 | ((unsigned __int64)*(unsigned __int8 *)(v14 + 34) << 31)) == 0x7FFFFFFFEi64 )
v15 = 80;
}
v17 = *(_DWORD *)(v6 + 32);
HIDWORD(a11) = v17;
if( (v17 & 2) == 0 || v10 > PteBase + 0x3FFFFFFF78i64 || v10 < PteBase )
{
v17 |= 0x80000000;
HIDWORD(a11) = v17;
}
if( !*(_DWORD *)(v6 + 36) )
__incgsdword(0x2E9Cu);
v124 = 0;
v18 = v17 & 0x1F;
v19 = 0;
v20 = MmProtectToPteMask[v18] & 0xFFFF000000000E5Eui64 | 0x21;
if( v10 < PteBase || v10 > (unsigned __int64)MmGetPteLimit() )
{
v24 = MmProtectToPteMask[v18] & 0xFFFF000000000E5Eui64 | 0x121;
goto LABEL_41;
}
LeafVa = (__int64)((v10 << 25) - (PteBase << 25)) >> 16;
if( v10 >= (unsigned __int64)MmGetPdeBase() && v10 <= (unsigned __int64)MmGetPdeLimit() )
{
if( (_MMPTE *)v10 == MmGetPxeSelfRef() )
{
v20 = MmProtectToPteMask[v18] & 0x7FFF000000000E5Ei64 | 0x8000000000000021ui64;
}
else if( (v17 & 0x4000000) == 0 )
{
v20 = MmProtectToPteMask[v18] & 0x7FFF000000000E5Ei64 | 0x21;
}
v22 = MiUserPdeOrAbove(v10);
PteBase = (unsigned __int64)MmGetPteBase();
if( v22 )
v20 |= 4ui64;
}
v23 = v20;
v24 = v20 | 4;
if( v10 > PteBase + 0x3FFFFFFF78i64 )
v24 = v23;
if( (v17 & 0x4000000) != 0 )
LeafVa = MiGetLeafVa(LeafVa);
if( LeafVa < 0xFFFF800000000000ui64 )
{
v25 = HIBYTE(word_140C4DD48);
LABEL_38:
if( v25 )
v24 |= 0x100ui64;
goto LABEL_40;
}
if( (unsigned int)MiGetSystemRegionType(LeafVa) != 1
&& (LeafVa < (unsigned __int64)MmGetPteBase() || LeafVa > (unsigned __int64)MmGetPteLimit()) )
{
if( LeafVa < qword_140C4F878 || (v25 = HIBYTE(word_140C4DD48), LeafVa > qword_140C4E0A8) )
v25 = (unsigned __int8)word_140C4DD48;
goto LABEL_38;
}
LABEL_40:
v3 = a3;
v19 = 0;
LABEL_41:
if( v17 < 0 && (v17 & 5) == 4 )
v24 |= 0x42ui64;
v26 = v24 & 0xFFFFFFFFFFFFFFFBui64;
if( (v17 & 0x40000000) == 0 )
v26 = v24;
if( (v17 & 0x20000000) != 0 )
v26 ^= ((unsigned __int16)v26 ^ (unsigned __int16)((unsigned __int8)word_140C4DD48 << 8)) & 0x100;
PxeUserLimit = MmGetPxeUserLimit();
v28 = v26 & 0xFFFFFFFFFFFFFEFFui64;
PfnDb = MmGetPfnDb();
v30 = 0i64;
if( (v17 & 0x8000000) == 0 )
v28 = v26;
v108 = 0i64;
v31 = v28 | 0x80;
if( (v17 & 0x4000000) == 0 )
v31 = v28;
v32 = v31 & 0xF0FFFFFFFFFFFFFFui64 | 0xA00000000000000i64;
Pml4eBase = MmGetPml4eBase();
if( !v3 )
{
LABEL_190:
v83 = MmGetPfnDb();
v84 = 273;
goto LABEL_191;
}
while( 1 )
{
v34 = *(_QWORD *)v10;
if( v10 >= (unsigned __int64)Pml4eBase && v10 <= (unsigned __int64)PxeUserLimit )
v30 = v108;
if( *(_DWORD *)(v6 + 36) )
{
if( (v34 & 0x400) == 0 && (v34 & 0x4000000) != 0 && !v30 )
v32 |= 0x40ui64;
}
else if( !v34 )
{
v34 = 32i64 * (*(_DWORD *)(v6 + 32) & 0x1F);
v124 = v19 + 1;
if( qword_140C4DC80 )
{
if( (v34 & qword_140C4DC80) != 0 )
v34 |= 0x10ui64;
else
v34 |= qword_140C4DC80;
}
*(_QWORD *)v10 = v34;
PfnDb = MmGetPfnDb();
}
v35 = (volatile signed __int64 *)(rdx0 + 24);
a12 = rdx0;
v36 = *(_QWORD *)(rdx0 + 24) & 0xFFFFFFFFFi64;
v37 = rdx0;
if( v36 == 0xFFFFFFFFFi64 )
v122 = 0i64;
else
v122 = (INT64)PfnDb + 48 * v36;
v38 = *v35;
v39 = _InterlockedCompareExchange64(v35, *v35 & 0xFFFFFFF000000000ui64, *v35);
if( v38 != v39 )
{
do
{
v40 = v39;
v39 = _InterlockedCompareExchange64(v35, v39 & 0xFFFFFFF000000000ui64, v39);
}
while( v40 != v39 );
}
v41 = (rdx0 - (__int64)MmGetPfnDb()) / 48;
v42 = *(_DWORD *)(v6 + 36) == 0;
a1 = v41;
if( !v42 && !*(_QWORD *)(v6 + 72) && (v34 & 0x400) != 0 )
{
v43 = v34;
if( qword_140C4DC80 && (v34 & 0x10) == 0 )
v43 = v34 & ~qword_140C4DC80;
if( v43 >> 16 )
{
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)v35, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)v35 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)v35, 0x3Fui64) );
v37 = rdx0;
}
*(_QWORD *)(v37 + 40) = *(_QWORD *)(v37 + 40) & 0x8FFFFFFFFFFFFFFFui64 | 0x4000000000000000i64;
_InterlockedAnd64(v35, 0x7FFFFFFFFFFFFFFFui64);
}
else if( (v34 & 0x3E0) != 0 )
{
v34 &= ~0x400ui64;
}
else
{
v34 = 0i64;
}
LODWORD(v44) = MiMapPageInHyperSpaceWorker(v41, 0i64, 0x80000000ui64);
memset64(v44, v34 & 0xFFFFFFFFFFFFFFFDui64, 0x200ui64);
MiUnmapPageInHyperSpaceWorker(v44, 0x11u, 0x80000000ui64);
v34 = MiSwizzleInvalidPte(128i64);
v15 |= 8u;
v37 = rdx0;
}
v45 = (WCHAR *)*(unsigned int *)(v6 + 32);
v46 = v15 | 0x20;
v47 = *(_QWORD *)v10;
if( (*(_DWORD *)v6 & 4) == 0 )
v46 = v15;
v48 = v46 | 0x20;
if( (*(_DWORD *)(v6 + 32) & 2) == 0 )
v48 = v46;
LODWORD(a11) = v48;
if( (v48 & 4) != 0 )
{
v49 = 32i64 * (*(_DWORD *)(v6 + 32) & 0x1F);
if( v47 )
v47 = v49 | v47 & 0xFFFFFFFFFFFFFC1Fui64;
else
v47 = MiSwizzleInvalidPte(v49);
}
v50 = -9i64;
if( (v47 & 0x400) != 0 )
v50 = -2049i64;
v51 = v47 & v50;
*(_QWORD *)(v37 + 16) = v51;
if( (v48 & 2) != 0 )
{
*(_QWORD *)(v37 + 40) |= 0x8000000000000000ui64;
}
else if( (v48 & 8) == 0 )
{
*(_QWORD *)v37 &= 0xFFFFFFFFFFFFC00Fui64;
*(_QWORD *)(v37 + 16) = v51 & 0xFFFFFFFFFC00FFFFui64;
}
if( (_DWORD)v45 )
{
if( (_DWORD)v45 == 31 )
{
v52 = 1;
v53 = 0i64;
}
else if( (unsigned int)v45 >> 3 == 3 && ((unsigned __int8)v45 & 7) != 0 )
{
v52 = 2;
v53 = 0i64;
}
else
{
v52 = 1;
v53 = 0i64;
if( (unsigned int)v45 >> 3 == 1 )
v52 = 0;
}
}
else
{
v52 = 3;
v53 = 0i64;
}
*(_WORD *)(v37 + 32) = 1;
v107 = *(_QWORD *)((char *)MmGetPteBase() + ((v10 >> 9) & 0x7FFFFFFFF8i64));
v54 = (v107 >> 12) & 0xFFFFFFFFFi64;
*(_QWORD *)(v37 + 40) = v54 | *(_QWORD *)(v37 + 40) & 0xFFFFFFF000000000ui64;
v55 = (char *)MmGetPfnDb() + 48 * v54;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v57 = *((_DWORD *)CurrentThread + 326);
if( (v57 & 0x100) != 0 )
{
v58 = v57 >> 9;
}
else
{
v58 = (*((_DWORD *)CurrentThread + 324) >> 12) & 7;
if( (*(_DWORD *)(*((_QWORD *)CurrentThread + 68) + 1124i64) & 0x100000) != 0 )
{
v59 = 2;
if( v58 < 2 )
v59 = v58;
LOBYTE(v58) = v59;
}
}
v60 = 17;
v61 = v48 & 1;
if( (v48 & 1) == 0 )
{
if( (v48 & 0x10) != 0 )
{
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v35, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *(__int64 *)v35 < 0 );
}
}
else
{
v60 = MiLockPageInline(v37);
}
}
LODWORD(v105) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v55 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v105);
while( *((__int64 *)v55 + 3) < 0 );
}
*((_QWORD *)v55 + 3) ^= ((*((_QWORD *)v55 + 3) + 1i64) ^ *((_QWORD *)v55 + 3)) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64((volatile signed __int64 *)v55 + 3, 0x7FFFFFFFFFFFFFFFui64);
v62 = *(_BYTE *)(a12 + 34);
if( v62 >> 6 == v52 )
{
v64 = a12;
}
else
{
v63 = v52;
v64 = a12;
MiChangePageAttribute(a12, v63, 1);
v62 = *(_BYTE *)(a12 + 34);
}
*v35 = *v35 & 0xC000000000000000ui64 | 1;
v65 = v58 ^ *(_BYTE *)(v64 + 35);
v66 = v111;
*(_QWORD *)(v64 + 8) = v111;
*(_BYTE *)(v64 + 35) ^= v65 & 7;
*(_BYTE *)(v64 + 34) = v62 & 0xF8 | 6;
if( (a11 & 0x20) == 0 )
*(_BYTE *)(v64 + 34) |= 0x10u;
if( (a11 & 0x40) != 0 )
*(_BYTE *)(v64 + 35) |= 0x20u;
if( !v61 )
{
_InterlockedAnd64(v35, 0x7FFFFFFFFFFFFFFFui64);
if( (a11 & 0x10) == 0 )
__writecr8(v60);
}
v15 = a11;
if( (a11 & 8) != 0 )
*(_QWORD *)(v64 + 16) = v34;
v6 = rcx0;
if( (*(_DWORD *)rcx0 & 4) != 0 )
{
*(_QWORD *)v66 = MiMakeTransitionPte(a1, *(unsigned int *)(rcx0 + 32), v53);
if( (*(_DWORD *)rcx0 & 0x40) != 0 )
_InterlockedExchangeAdd64((volatile signed __int64 *)(v101 + 1272), 1ui64);
MiLockAndDecrementShareCount(v64, 0);
if( v112
&& (__int64)((v66 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16 == *(_QWORD *)(v112[1] + 16i64 * v112[3])
+ (v112[4] << 12)
&& *(_BYTE *)v112 != 5 )
{
MiAdvanceFaultList(v112);
}
goto LABEL_189;
}
v32 = (v32 ^ (a1 << 12)) & 0xFFFFFFFFF000i64 ^ v32 | 0x20;
if( *(_QWORD *)(rcx0 + 72) )
{
*(_QWORD *)v66 = v32;
goto LABEL_189;
}
if( v66 == v113
|| (*(_DWORD *)rcx0 & 0x80u) == 0
|| (v32 &= ~0x20ui64, a11 >= 0)
|| (v67 = MmGetPteBase(), v66 > (unsigned __int64)v67 + 0x3FFFFFFF78i64) )
{
v68 = v101;
}
else
{
v68 = v101;
if( v66 >= (unsigned __int64)v67 && (*(_DWORD *)(v101 + 1124) & 0x8000) != 0 )
{
if( HIDWORD(a9) )
{
if( HIDWORD(a9) == 2 )
v32 &= 0xFFFFFFFFFFFFFFBDui64;
}
else
{
Address = v114;
if( !v114 )
Address = MiLocateAddress(*(_QWORD *)(rcx0 + 16));
if( ((__int64)Address[2].Children[0] & 0x300000) == 3145728 )
{
HIDWORD(a9) = 2;
v32 &= 0xFFFFFFFFFFFFFFBDui64;
}
else
{
HIDWORD(a9) = 1;
}
}
}
}
v70 = *(_QWORD *)(rcx0 + 8);
v71 = (UNICODE_STRING *)*(unsigned __int8 *)(v70 + 69);
if( ((unsigned __int8)v71 & 5) != 4 || ((unsigned __int8)v71 & 2) != 0 )
{
v81 = a9 & 0xFFFFFFFB;
LODWORD(a9) = a9 & 0xFFFFFFFB;
goto LABEL_185;
}
v72 = *(unsigned __int16 *)(v70 + 66);
v73 = 511;
if( (_WORD)v72 )
{
if( v72 + *(unsigned __int16 *)(v70 + 64) == (((unsigned int)v66 >> 3) & 0x1FF) )
{
LOBYTE(v71) = (unsigned __int8)v71 & 0x10;
LOBYTE(v74) = MI_PFN_IS_PROTO((UNICODE_STRING *)v64, v71, 0xFFu, v45);
if( v74 )
{
if( !v75 )
goto LABEL_175;
}
else if( v75 )
{
goto LABEL_175;
}
}
MiEmptyDeferredWorkingSetEntries(v70 + 56);
v73 = 511;
}
LABEL_175:
v76 = *(_WORD *)(v70 + 66);
if( v76 )
{
*(_WORD *)(v70 + 66) = v76 + 1;
}
else
{
v77 = (UNICODE_STRING *)*(unsigned __int8 *)(v70 + 69);
*(_WORD *)(v70 + 66) = 1;
*(_WORD *)(v70 + 64) = v73 & ((unsigned int)v66 >> 3);
LOBYTE(v78) = MI_PFN_IS_PROTO((UNICODE_STRING *)v64, v77, v73, v45);
if( v78 )
*(_BYTE *)(v70 + 69) = v79 & 0xEF;
else
*(_BYTE *)(v70 + 69) = v79 | 0x10;
}
v80 = *(_QWORD *)(rcx0 + 8);
v81 = a9 | 4;
LODWORD(a9) = a9 | 4;
if( (*(_BYTE *)(v80 + 69) & 8) != 0 )
{
v82 = *(_QWORD *)(v80 + 16);
if( (v82 & 1) == 0 || *(_BYTE *)(v82 & 0xFFFFFFFFFFFFFFFEui64) != 2 )
v32 &= ~0x20ui64;
}
LABEL_185:
LODWORD(a6) = v81;
if( !(unsigned int)MiAllocateWsle(v116, v66, (_QWORD *)v64, 0, v32, a6, v115) )
break;
if( (*(_DWORD *)rcx0 & 0x40) != 0 )
_InterlockedExchangeAdd64((volatile signed __int64 *)(v68 + 1272), 1ui64);
__incgsdword(0x2E9Cu);
LABEL_189:
v10 = v66 + 8;
rdx0 = v122;
v30 = v108 + 1;
v19 = v124;
v108 = v30;
v111 = v10;
PxeUserLimit = MmGetPxeUserLimit();
Pml4eBase = MmGetPml4eBase();
if( v30 >= a3 )
goto LABEL_190;
PfnDb = MmGetPfnDb();
}
v83 = MmGetPfnDb();
v88 = (UINT64)v83 + 48 * (*(_QWORD *)(v64 + 40) & 0xFFFFFFFFFi64);
HIDWORD(v105) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v64 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v105 + 4));
while( *(__int64 *)(v64 + 24) < 0 );
}
MiCapturePageFileInfoInline((UINT64 *)(v64 + 16), 1i64, 0i64);
*(_QWORD *)(v64 + 16) &= ~2ui64;
*(_QWORD *)(v64 + 24) |= 0x4000000000000000ui64;
MiDecrementShareCount(v64);
_InterlockedAnd64((volatile signed __int64 *)(v64 + 24), 0x7FFFFFFFFFFFFFFFui64);
MiLockAndDecrementShareCount(v88, 0);
v84 = -1073741801;
MiFreePageChain(v122, v89, v90, v91, a5, a6, a7, v99, a9, v101, a11, a12);
LABEL_191:
if( !*(_DWORD *)(v6 + 36) && v124 )
{
v85 = 0;
v86 = *(_QWORD *)(v6 + 16);
v87 = MmGetPteBase();
while( v86 > 0x7FFFFFFEFFFFi64 )
{
++v85;
v86 = (__int64)((v86 << 25) - ((_QWORD)v87 << 25)) >> 16;
if( v85 >= 3 )
return v84;
}
v109 = *(_QWORD *)((char *)MmGetPdeBase() + ((*(_QWORD *)(v6 + 16) >> 18) & 0x3FFFFFF8i64));
v92 = (char *)v83 + 48 * ((v109 >> 12) & 0xFFFFFFFFFi64);
LODWORD(v106) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v92 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v106);
while( *((__int64 *)v92 + 3) < 0 );
}
*((_QWORD *)v92 + 2) ^= ((unsigned int)*((_QWORD *)v92 + 2) ^ ((unsigned int)*((_QWORD *)v92 + 2)
+ ((unsigned __int16)v124 << 16))) & 0x3FF0000;
_InterlockedAnd64((volatile signed __int64 *)v92 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( v124 <= 1
&& ((__int64)(*((_QWORD *)v92 + 1) | 0x8000000000000000ui64) >> 47 == -1
|| (__int64)(*((_QWORD *)v92 + 1) | 0x8000000000000000ui64) >> 47 == 0) )
{
v117 = (unsigned __int64)v87 + (((*((_QWORD *)v92 + 1) | 0x8000000000000000ui64) >> 9) & 0x7FFFFFFFF8i64);
v118 = (unsigned __int64)v87 + ((v117 >> 9) & 0x7FFFFFFFF8i64);
v119 = (unsigned __int64)v87 + ((v118 >> 9) & 0x7FFFFFFFF8i64);
v120 = (__int64)v87 + ((v119 >> 9) & 0x7FFFFFFFF8i64);
v93 = 4i64;
do
v94 = (_QWORD *)*(&v116 + v93--);
while( (*v94 & 1) != 0 && (*v94 & 0x80u) == 0i64 && v93 );
}
}
return v84;
}Referenced by:
MiResolvePrivateZeroFault