NtGetWriteWatch
NTSTATUS __stdcall NtGetWriteWatch(
PVOID ProcessHandle,
UINT64 Flags,
PVOID BaseAddress,
UINT64 RegionSize,
PVOID *UserAddressArray,
UINT64 *EntriesInUserAddressArray,
UINT64 *Granularity){
int v9;
_ETHREAD *CurrentThread;
_EPROCESS *v11;
KPROCESSOR_MODE v12;
__int64 v13;
UINT64 v14;
__int64 v15;
UINT64 v16;
char *v18;
int v19;
__int64 v20;
int v21;
_EPROCESS *v22;
unsigned __int64 v23;
_MMPTE *PteBase;
unsigned __int64 v25;
__int64 v26;
INT64 v27;
unsigned __int64 VadMandatoryPageSize;
unsigned int v29;
unsigned __int64 v30;
unsigned __int64 v31;
unsigned __int64 v32;
unsigned __int64 v33;
INT64 v34;
UINT64 v35;
INT64 v36;
INT64 v37;
unsigned __int64 v38;
INT64 v39;
unsigned __int64 v40;
__int64 v41;
unsigned __int64 v42;
unsigned __int64 v43;
unsigned __int64 v44;
unsigned __int64 v45;
__int64 v46;
UINT64 LeafVa;
INT64 v48;
int v49;
char v50;
NTSTATUS v51;
char *v52;
unsigned __int64 v53;
__int64 v54;
UINT64 *v55;
UINT64 v56;
UINT64 v57;
__int64 v58;
UINT64 *v59;
_MMPTE *v60;
unsigned __int64 v61;
__int64 v62;
unsigned __int64 v63;
char v64;
unsigned int j;
char v66;
char v67;
INT64 i;
__int64 v69;
INT64 ***LockedVadEvent;
int v71;
INT64 v72;
UINT64 v73;
unsigned __int64 v74;
void *Src;
PVOID Object;
unsigned int a6;
UINT64 v78;
UINT64 *v79;
INT64 a2;
unsigned __int64 v81;
__int64 v82;
PVOID P;
HANDLE Handle;
UINT8 *dst;
UINT64 *v86;
UINT64 *v87;
struct _KAPC_STATE ApcState;
INT64 v89[4];
INT64 result[20];
char v91[2048];
v9 = Flags;
v71 = Flags;
Handle = ProcessHandle;
dst = (UINT8 *)UserAddressArray;
v86 = EntriesInUserAddressArray;
v87 = Granularity;
Object = 0i64;
a6 = 0;
LODWORD(i) = 0;
memset(&ApcState, 0, sizeof(ApcState));
memset((INT64)result, 0i64);
v89[1] = 20i64;
v89[0] = 1i64;
v89[2] = 0i64;
v89[3] = 0i64;
if( (v9 & 0xFFFFFFFE) != 0 )
return -1073741584;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v11 = (_EPROCESS *)*((_QWORD *)CurrentThread + 23);
v12 = *((_BYTE *)CurrentThread + 562);
if( v12 )
{
if( (unsigned __int64)BaseAddress > 0x7FFFFFFEFFFFi64 )
return -1073741583;
if( 0x7FFFFFFF0000i64 - (__int64)BaseAddress < RegionSize )
return -1073741582;
v13 = (__int64)EntriesInUserAddressArray;
if( (unsigned __int64)EntriesInUserAddressArray >= 0x7FFFFFFF0000i64 )
v13 = 0x7FFFFFFF0000i64;
*(_QWORD *)v13 = *(_QWORD *)v13;
v14 = *EntriesInUserAddressArray;
v78 = v14;
if( !v14 )
return -1073741581;
if( v14 > 0x1FFFFFFFFFFFFFFFi64 )
return -1073741581;
ProbeForWrite(UserAddressArray, 8 * v14, 8ui64);
v15 = (__int64)Granularity;
if( (unsigned __int64)Granularity >= 0x7FFFFFFF0000i64 )
v15 = 0x7FFFFFFF0000i64;
*(_DWORD *)v15 = *(_DWORD *)v15;
v16 = v78;
}
else
{
v16 = *EntriesInUserAddressArray;
v78 = *EntriesInUserAddressArray;
}
v18 = v91;
Src = v91;
if( v16 > 0x100 )
{
LODWORD(v18) = MiAllocatePool((struct _SLIST_ENTRY *)0x41);
Src = v18;
if( !v18 )
return -1073741670;
}
v19 = 1;
v20 = 0i64;
v73 = 0i64;
v79 = (UINT64 *)v18;
P = 0i64;
v21 = 0;
if( Handle == (HANDLE)-1i64 )
{
v22 = v11;
}
else
{
v51 = ObReferenceObjectByHandleWithTag(Handle, 8u, (POBJECT_TYPE)PsProcessType, v12, 0x77576D4Du, &Object, 0i64);
LODWORD(i) = v51;
if( v51 < 0 )
goto LABEL_118;
v22 = (_EPROCESS *)Object;
}
Object = v22;
v69 = 0i64;
v23 = (unsigned __int64)BaseAddress + RegionSize - 1;
if( (unsigned __int64)BaseAddress > v23 )
{
v51 = -1073741582;
goto LABEL_58;
}
if( v11 != v22 )
{
KeStackAttachProcess((PRKPROCESS)v22, &ApcState);
v21 = 1;
v22 = (_EPROCESS *)Object;
}
v72 = (INT64)v22 + 1664;
PteBase = MmGetPteBase();
v25 = (unsigned __int64)PteBase + (((unsigned __int64)BaseAddress >> 9) & 0x7FFFFFFFF8i64);
a2 = (INT64)PteBase + ((v23 >> 9) & 0x7FFFFFFFF8i64);
v26 = MiObtainReferencedVadEx((UINT64)BaseAddress, 0, &i);
v27 = v26;
v82 = v26;
if( !v26 )
{
v51 = i;
v20 = v69;
if( (_DWORD)i != -1073741664 )
goto LABEL_58;
LABEL_80:
v51 = -1073741585;
goto LABEL_58;
}
P = (PVOID)v26;
if( (*(_DWORD *)(v26 + 48) & 0x300000) != 3145728
|| v23 > (((*(unsigned int *)(v26 + 28) | ((unsigned __int64)*(unsigned __int8 *)(v26 + 33) << 32)) << 12) | 0xFFF) )
{
v20 = v69;
goto LABEL_80;
}
VadMandatoryPageSize = MiGetVadMandatoryPageSize(v26);
v19 = VadMandatoryPageSize;
v74 = VadMandatoryPageSize;
if( VadMandatoryPageSize <= 1 )
goto LABEL_27;
v58 = (VadMandatoryPageSize << 12) - 1;
if( ((unsigned __int64)BaseAddress & v58) != 0 )
{
v51 = -1073741583;
v20 = v69;
goto LABEL_58;
}
if( (RegionSize & v58) != 0 )
{
v51 = -1073741582;
v20 = v69;
}
else
{
LABEL_27:
if( (v29 & 0x500000) == 5242880 )
{
v30 = 16i64;
if( MiVadPageSizes[((unsigned __int64)v29 >> 18) & 3] != 16 )
v30 = 1i64;
}
else
{
v30 = 1i64;
}
LockedVadEvent = MiLocateLockedVadEvent(v27, 4i64);
v31 = ((unsigned __int64)BaseAddress >> 12)
- (*(unsigned int *)(v27 + 24) | ((unsigned __int64)*(unsigned __int8 *)(v27 + 32) << 32));
v32 = v74;
v33 = v31 / v74;
v34 = v72;
v67 = MiLockWorkingSetShared(v72);
if( v25 <= a2 )
{
while( 1 )
{
v35 = v73;
if( v73 )
{
MiFlushTbList((__int64)v89);
v57 = v35;
v36 = v72;
MiUnlockPageTable(v72, v57);
v73 = 0i64;
}
else
{
v36 = v72;
}
if( MiWorkingSetIsContended(v36) || MiShouldYieldProcessor() )
{
MiUnlockWorkingSetShared(v36, v67);
MiLockWorkingSetShared(v36);
}
v37 = a2;
MiGetNextPageTable(v25, a2, 0i64, v67, 1, &a6);
v39 = v38;
if( v38 )
v73 = (UINT64)MmGetPteBase() + ((v38 >> 9) & 0x7FFFFFFFF8i64);
else
v39 = v37 + 8;
v40 = ((__int64)(v39 - v25) >> 3) / v32;
v21 |= 4u;
MiLockVadCore(v27);
v41 = (__int64)LockedVadEvent;
if( v40 )
break;
LABEL_38:
if( v25 > a2 )
goto LABEL_52;
v42 = a2;
i = a2;
if( a6 )
{
v25 = v73;
v60 = MmGetPteBase();
v61 = (unsigned __int64)v60 + (((unsigned __int64)a2 >> 9) & 0x7FFFFFFFF8i64);
v43 = 512i64;
if( a6 > 1 )
{
v62 = a6 - 1;
do
{
v43 <<= 9;
v25 = (unsigned __int64)v60 + ((v25 >> 9) & 0x7FFFFFFFF8i64);
v61 = (unsigned __int64)v60 + ((v61 >> 9) & 0x7FFFFFFFF8i64);
--v62;
}
while( v62 );
}
v73 = (UINT64)v60 + ((v25 >> 9) & 0x7FFFFFFFF8i64);
v63 = v25 + 8;
for( i = v25 + 8; (v63 & 0xFFF) != 0; i = v63 )
{
if( v63 > v61 )
break;
v64 = MI_READ_PTE_LOCK_FREE(v63);
v63 = i;
if( (v64 & 0x81) != 0x81 )
break;
v63 = i + 8;
}
v42 = v63 - 8;
i = v42;
v32 = v74;
}
else
{
v43 = v30;
}
v81 = v43 / v32;
if( v25 <= v42 )
{
while( 1 )
{
LeafVa = MiGetLeafVa(v25);
v21 &= ~2u;
v48 = v25;
if( _bittest64(*(const signed __int64 **)(v46 + 16), v33) != 1 )
{
v49 = 0;
while( 1 )
{
v50 = MI_READ_PTE_LOCK_FREE(v48);
if( (v50 & 0x42) != 0 && (v50 & 1) != 0 )
{
v21 |= 2u;
if( (v71 & 1) == 0 )
goto LABEL_46;
MiMakePteClean(v48, (INT64)v89);
}
v48 += 8i64;
if( (unsigned int)++v49 >= v30 )
goto LABEL_46;
}
}
v21 |= 2u;
if( (v71 & 1) != 0 )
{
_bittestandreset64(*(signed __int64 **)(v46 + 16), v33);
for( j = 0; j < v30; ++j )
{
v66 = MI_READ_PTE_LOCK_FREE(v48);
if( (v66 & 0x42) != 0 && (v66 & 1) != 0 )
MiMakePteClean(v48, (INT64)v89);
v48 += 8i64;
}
LABEL_46:
v44 = v81;
v45 = i;
v32 = v74;
}
if( (v21 & 2) != 0 )
{
v53 = 0i64;
if( v44 )
break;
}
LABEL_48:
v33 += v44;
v25 += 8 * v30;
if( (v25 & 0xFFF) == 0 || v25 > v45 )
{
v27 = v82;
goto LABEL_51;
}
}
v54 = v69;
v55 = v79;
v56 = v78;
while( 1 )
{
*v55++ = LeafVa;
v79 = v55;
v69 = ++v54;
if( v54 == v56 )
break;
++v53;
LeafVa += v32 << 12;
if( v53 >= v44 )
goto LABEL_48;
}
v27 = v82;
goto LABEL_52;
}
LABEL_51:
MiUnlockVadCore(v27, 2u);
v21 &= ~4u;
v25 = (unsigned __int64)MmGetPteBase() + ((MiGetLeafVa(v25) >> 9) & 0x7FFFFFFFF8i64);
if( v25 > a2 )
goto LABEL_52;
}
while( 1 )
{
if( _bittest64(*(const signed __int64 **)(v41 + 16), v33) == 1 )
{
if( (v71 & 1) != 0 )
_bittestandreset64(*(signed __int64 **)(v41 + 16), v33);
v59 = v79;
*v79 = (__int64)((v25 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
v79 = v59 + 1;
if( ++v69 == v78 )
break;
}
++v33;
v25 += 8 * v32;
if( !--v40 )
goto LABEL_38;
}
LABEL_52:
v34 = v72;
}
MiFlushTbList((__int64)v89);
if( (v21 & 4) != 0 )
MiUnlockVadCore(v27, 2u);
if( v73 )
MiUnlockPageTable(v34, v73);
MiUnlockWorkingSetShared(v34, v67);
v51 = 0;
v19 = v74;
v20 = v69;
}
LABEL_58:
if( P )
MiUnlockAndDereferenceVad(P);
if( (v21 & 1) != 0 )
KeUnstackDetachProcess(&ApcState);
if( Handle != (HANDLE)-1i64 )
ObfDereferenceObjectWithTag(Object, 0x77576D4Dui64);
if( !v51 )
{
v52 = (char *)Src;
if( dst )
{
memmove(dst, (UINT8 *)Src, 8 * v20);
*v86 = v20;
}
*(_DWORD *)v87 = v19 << 12;
goto LABEL_68;
}
LABEL_118:
v52 = (char *)Src;
LABEL_68:
if( v52 != v91 )
ExFreePoolWithTag(v52, 0);
return v51;
}Referenced by:
No references.