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.