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.