NtGetWriteWatch
NTSTATUS __stdcall NtGetWriteWatch(
VOID *ProcessHandle,
UINT64 Flags,
VOID *BaseAddress,
UINT64 RegionSize,
VOID **UserAddressArray,
UINT64 *EntriesInUserAddressArray,
UINT64 *Granularity){
int v9;
_ETHREAD *CurrentThread;
_EPROCESS *Process;
INT8 PreviousMode;
__int64 v13;
UINT64 v14;
__int64 v15;
UINT64 v16;
char *Pool;
int v19;
__int64 v20;
int v21;
_EPROCESS *v22;
unsigned __int64 v23;
_MMPTE *PteBase;
unsigned __int64 v25;
_MMVAD_SHORT *v26;
__int64 v27;
unsigned __int64 v28;
unsigned int v29;
unsigned __int64 v30;
unsigned __int64 v31;
unsigned __int64 v32;
unsigned __int64 v33;
_MMSUPPORT_INSTANCE *v34;
UINT8 v35;
UINT64 v36;
_MMSUPPORT_INSTANCE *v37;
int v38;
_MMPTE *v39;
_MMPTE *NextPageTable;
_MMPTE *v41;
unsigned __int64 v42;
__int64 v43;
_MMPTE *v44;
unsigned __int64 v45;
__int64 v46;
unsigned __int64 v47;
unsigned __int64 v48;
__int64 v49;
__int64 v50;
INT64 v51;
int v52;
char v53;
unsigned __int64 v54;
NTSTATUS v55;
char *v56;
unsigned __int64 v57;
__int64 v58;
_QWORD *v59;
UINT64 v60;
UINT64 v61;
__int64 v62;
_QWORD *v63;
_MMPTE *v64;
unsigned __int64 v65;
__int64 v66;
unsigned __int64 v67;
char v68;
unsigned int j;
char v70;
UINT64 PageTableFlags;
POBJECT_HANDLE_INFORMATION HandleInformation;
UINT8 v73;
INT64 i;
__int64 v75;
__int64 ********LockedVadEvent;
int v77;
INT64 p_Vm;
UINT64 v79;
unsigned __int64 v80;
VOID *Src;
PVOID Object;
UINT64 LargePage;
UINT64 v84;
_QWORD *v85;
_MMPTE *LastPte;
unsigned __int64 v87;
_MMVAD_SHORT *v88;
_MMVAD_SHORT *Vad;
_HANDLE Handle[2];
VOID *v91;
UINT64 *v92;
UINT64 *v93;
_KAPC_STATE ApcState;
_MI_TB_FLUSH_LIST TbFlushList;
__int16 v96;
__int16 v97;
__int64 v98;
__int64 v99;
__int64 v100;
char v101[152];
char v102[2048];
v9 = Flags;
v77 = Flags;
*(_QWORD *)Handle = ProcessHandle;
v91 = UserAddressArray;
v92 = EntriesInUserAddressArray;
v93 = Granularity;
Object = 0i64;
LODWORD(LargePage) = 0;
LODWORD(i) = 0;
memset(&ApcState, 0, sizeof(ApcState));
v97 = 0;
memset(v101, 0i64, sizeof(v101));
v98 = 20i64;
TbFlushList = 1;
v96 = 0;
v99 = 0i64;
v100 = 0i64;
if( (v9 & 0xFFFFFFFE) != 0 )
return -1073741584;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Process = CurrentThread->Tcb.ApcState.Process;
PreviousMode = CurrentThread->Tcb.PreviousMode;
if( PreviousMode )
{
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;
v84 = v14;
if( !v14 )
return -1073741581;
if( v14 > 0x1FFFFFFFFFFFFFFFi64 )
return -1073741581;
ProbeForWrite((UINT64)UserAddressArray, 8 * v14, 8i64);
v15 = (__int64)Granularity;
if( (unsigned __int64)Granularity >= 0x7FFFFFFF0000i64 )
v15 = 0x7FFFFFFF0000i64;
*(_DWORD *)v15 = *(_DWORD *)v15;
v16 = v84;
}
else
{
v16 = *EntriesInUserAddressArray;
v84 = *EntriesInUserAddressArray;
}
Pool = v102;
Src = v102;
if( v16 > 0x100 )
{
Pool = (char *)MiAllocatePool(65i64, 8 * v16, 0x63476D4Dui64);
Src = Pool;
if( !Pool )
return -1073741670;
}
v19 = 1;
v20 = 0i64;
v79 = 0i64;
v85 = Pool;
Vad = 0i64;
v21 = 0;
if( *(_QWORD *)Handle == -1i64 )
{
v22 = Process;
}
else
{
LODWORD(PageTableFlags) = 2002218317;
v55 = ObReferenceObjectByHandleWithTag(
*(VOID **)Handle,
8ui64,
(_OBJECT_TYPE *)PsProcessType,
PreviousMode,
PageTableFlags,
&Object,
0i64);
LODWORD(i) = v55;
if( v55 < 0 )
goto LABEL_118;
v22 = (_EPROCESS *)Object;
}
Object = v22;
v75 = 0i64;
v23 = (unsigned __int64)BaseAddress + RegionSize - 1;
if( (unsigned __int64)BaseAddress > v23 )
{
v55 = -1073741582;
goto LABEL_58;
}
if( Process != v22 )
{
KeStackAttachProcess(&v22->Pcb, &ApcState);
v21 = 1;
v22 = (_EPROCESS *)Object;
}
p_Vm = (INT64)&v22->Vm;
PteBase = MmGetPteBase();
v25 = (unsigned __int64)PteBase + (((unsigned __int64)BaseAddress >> 9) & 0x7FFFFFFFF8i64);
LastPte = (_MMPTE *)((char *)PteBase + ((v23 >> 9) & 0x7FFFFFFFF8i64));
LODWORD(v26) = MiObtainReferencedVadEx((UINT64)BaseAddress, 0, &i);
v27 = (__int64)v26;
v88 = v26;
if( !v26 )
{
v55 = i;
v20 = v75;
if( (_DWORD)i != -1073741664 )
goto LABEL_58;
LABEL_80:
v55 = -1073741585;
goto LABEL_58;
}
Vad = v26;
if( (v26->u.LongFlags & 0x300000) != 3145728
|| v23 > (((v26->EndingVpn | ((unsigned __int64)v26->EndingVpnHigh << 32)) << 12) | 0xFFF) )
{
v20 = v75;
goto LABEL_80;
}
LODWORD(v28) = MiGetVadMandatoryPageSize((INT64)v26);
v19 = v28;
v80 = v28;
if( v28 <= 1 )
goto LABEL_27;
v62 = (v28 << 12) - 1;
if( ((unsigned __int64)BaseAddress & v62) != 0 )
{
v55 = -1073741583;
v20 = v75;
goto LABEL_58;
}
if( (RegionSize & v62) != 0 )
{
v55 = -1073741582;
v20 = v75;
}
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, 4);
v31 = ((unsigned __int64)BaseAddress >> 12)
- (*(unsigned int *)(v27 + 24) | ((unsigned __int64)*(unsigned __int8 *)(v27 + 32) << 32));
v32 = v80;
v33 = v31 / v80;
v34 = (_MMSUPPORT_INSTANCE *)p_Vm;
MiLockWorkingSetShared();
v73 = v35;
if( v25 <= (unsigned __int64)LastPte )
{
while( 1 )
{
v36 = v79;
if( v79 )
{
MiFlushTbList(&TbFlushList);
v61 = v36;
v37 = (_MMSUPPORT_INSTANCE *)p_Vm;
MiUnlockPageTable(p_Vm, v61);
v79 = 0i64;
}
else
{
v37 = (_MMSUPPORT_INSTANCE *)p_Vm;
}
LOBYTE(v38) = MiWorkingSetIsContended((INT64)v37);
if( v38 || MiShouldYieldProcessor() )
{
MiUnlockWorkingSetShared(v37, v73);
MiLockWorkingSetShared();
}
LODWORD(PageTableFlags) = 1;
v39 = LastPte;
NextPageTable = MiGetNextPageTable(
(_MMPTE *)v25,
LastPte,
0i64,
v73,
PageTableFlags,
&LargePage,
(UINT64)HandleInformation);
v41 = NextPageTable;
if( NextPageTable )
v79 = (UINT64)MmGetPteBase() + (((unsigned __int64)NextPageTable >> 9) & 0x7FFFFFFFF8i64);
else
v41 = v39 + 1;
v42 = ((__int64)((__int64)v41 - v25) >> 3) / v32;
v21 |= 4u;
MiLockVadCore(v27);
v43 = (__int64)LockedVadEvent;
if( v42 )
break;
LABEL_38:
if( v25 > (unsigned __int64)LastPte )
goto LABEL_52;
v44 = LastPte;
i = (INT64)LastPte;
if( (_DWORD)LargePage )
{
v25 = v79;
v64 = MmGetPteBase();
v65 = (unsigned __int64)v64 + (((unsigned __int64)LastPte >> 9) & 0x7FFFFFFFF8i64);
v45 = 512i64;
if( (unsigned int)LargePage > 1 )
{
v66 = (unsigned int)(LargePage - 1);
do
{
v45 <<= 9;
v25 = (unsigned __int64)v64 + ((v25 >> 9) & 0x7FFFFFFFF8i64);
v65 = (unsigned __int64)v64 + ((v65 >> 9) & 0x7FFFFFFFF8i64);
--v66;
}
while( v66 );
}
v79 = (UINT64)v64 + ((v25 >> 9) & 0x7FFFFFFFF8i64);
v67 = v25 + 8;
for( i = v25 + 8; (v67 & 0xFFF) != 0; i = v67 )
{
if( v67 > v65 )
break;
v68 = MI_READ_PTE_LOCK_FREE(v67);
v67 = i;
if( (v68 & 0x81) != 0x81 )
break;
v67 = i + 8;
}
v44 = (_MMPTE *)(v67 - 8);
i = (INT64)v44;
v32 = v80;
}
else
{
v45 = v30;
}
v87 = v45 / v32;
if( v25 <= (unsigned __int64)v44 )
{
while( 1 )
{
LODWORD(v46) = MiGetLeafVa(v25);
v50 = v46;
v21 &= ~2u;
v51 = v25;
if( _bittest64(*(const signed __int64 **)(v49 + 16), v33) != 1 )
{
v52 = 0;
while( 1 )
{
v53 = MI_READ_PTE_LOCK_FREE(v51);
if( (v53 & 0x42) != 0 && (v53 & 1) != 0 )
{
v21 |= 2u;
if( (v77 & 1) == 0 )
goto LABEL_46;
MiMakePteClean(v51, (INT64)&TbFlushList);
}
v51 += 8i64;
if( (unsigned int)++v52 >= v30 )
goto LABEL_46;
}
}
v21 |= 2u;
if( (v77 & 1) != 0 )
{
_bittestandreset64(*(signed __int64 **)(v49 + 16), v33);
for( j = 0; j < v30; ++j )
{
v70 = MI_READ_PTE_LOCK_FREE(v51);
if( (v70 & 0x42) != 0 && (v70 & 1) != 0 )
MiMakePteClean(v51, (INT64)&TbFlushList);
v51 += 8i64;
}
LABEL_46:
v47 = v87;
v48 = i;
v32 = v80;
}
if( (v21 & 2) != 0 )
{
v57 = 0i64;
if( v47 )
break;
}
LABEL_48:
v33 += v47;
v25 += 8 * v30;
if( (v25 & 0xFFF) == 0 || v25 > v48 )
{
v27 = (__int64)v88;
goto LABEL_51;
}
}
v58 = v75;
v59 = v85;
v60 = v84;
while( 1 )
{
*v59++ = v50;
v85 = v59;
v75 = ++v58;
if( v58 == v60 )
break;
++v57;
v50 += v32 << 12;
if( v57 >= v47 )
goto LABEL_48;
}
v27 = (__int64)v88;
goto LABEL_52;
}
LABEL_51:
MiUnlockVadCore(v27, 2u);
v21 &= ~4u;
LODWORD(v54) = MiGetLeafVa(v25);
v25 = (unsigned __int64)MmGetPteBase() + ((v54 >> 9) & 0x7FFFFFFFF8i64);
if( v25 > (unsigned __int64)LastPte )
goto LABEL_52;
}
while( 1 )
{
if( _bittest64(*(const signed __int64 **)(v43 + 16), v33) == 1 )
{
if( (v77 & 1) != 0 )
_bittestandreset64(*(signed __int64 **)(v43 + 16), v33);
v63 = v85;
*v85 = (__int64)((v25 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
v85 = v63 + 1;
if( ++v75 == v84 )
break;
}
++v33;
v25 += 8 * v32;
if( !--v42 )
goto LABEL_38;
}
LABEL_52:
v34 = (_MMSUPPORT_INSTANCE *)p_Vm;
}
MiFlushTbList(&TbFlushList);
if( (v21 & 4) != 0 )
MiUnlockVadCore(v27, 2u);
if( v79 )
MiUnlockPageTable((INT64)v34, v79);
MiUnlockWorkingSetShared(v34, v73);
v55 = 0;
v19 = v80;
v20 = v75;
}
LABEL_58:
if( Vad )
MiUnlockAndDereferenceVad(Vad);
if( (v21 & 1) != 0 )
KeUnstackDetachProcess(&ApcState);
if( *(_QWORD *)Handle != -1i64 )
ObfDereferenceObjectWithTag(Object, 0x77576D4Dui64);
if( !v55 )
{
v56 = (char *)Src;
if( v91 )
{
memmove(v91, Src, 8 * v20);
*v92 = v20;
}
*(_DWORD *)v93 = v19 << 12;
goto LABEL_68;
}
LABEL_118:
v56 = (char *)Src;
LABEL_68:
if( v56 != v102 )
ExFreePoolWithTag(v56, 0);
return v55;
}Referenced by:
No references.