MiCreateCloneChain

NTSTATUS __stdcall MiCreateCloneChain(_EPROCESS *ProcessToCharge, _MMCLONE_DESCRIPTOR **CloneChain){
  _ETHREAD *CurrentThread; 
  int v4; 
  _MMCLONE_DESCRIPTOR *v5; 
  UINT64 v6; 
  _EPROCESS *v7; 
  _MMSUPPORT_SHARED *SharedVm; 
  UINT8 v9; 
  UINT8 v10; 
  _RTL_BALANCED_NODE *Root; 
  _QWORD *Children; 
  _MMCLONE_DESCRIPTOR *Pool; 
  _QWORD **v14; 
  _QWORD *v15; 
  _QWORD *v16; 
  _MMCLONE_DESCRIPTOR *v17; 
  NTSTATUS result; 

  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  *CloneChain = 0i64;
  v4 = 0;
  v5 = 0i64;
  v6 = 0i64;
  v7 = CurrentThread->Tcb.ApcState.Process;
  SharedVm = MiGetSharedVm(&v7->Vm.Instance);
  v9 = ExAcquireSpinLockExclusive((INT64 *)&SharedVm->WorkingSetLock);
  SharedVm->GoodCitizenWaiting = 0;
  v10 = v9;
  Root = v7->CloneRoot.Root;
  Children = 0i64;
  while( Root )
  {
    Children = Root->Children;
    Root = Root->Children[0];
  }
  while( Children )
  {
    if( Children[6] )
    {
      Pool = (_MMCLONE_DESCRIPTOR *)MiAllocatePool(64i64, 0x70ui64, 0x64436D4Dui64);
      if( !Pool )
      {
        v4 = -1073741670;
        break;
      }
      Pool->CloneNode.Children[0] = &v5->CloneNode;
      v5 = Pool;
      Pool->NonPagedPoolQuotaCharge = Children[8];
      v6 += Children[8];
    }
    v14 = (_QWORD **)Children[1];
    v15 = Children;
    if( v14 )
    {
      v16 = *v14;
      for( Children = (_QWORD *)Children[1]; v16; v16 = (_QWORD *)*v16 )
        Children = v16;
    }
    else
    {
      while( 1 )
      {
        Children = (_QWORD *)(Children[2] & 0xFFFFFFFFFFFFFFFCui64);
        if( !Children || (_QWORD *)*Children == v15 )
          break;
        v15 = Children;
      }
    }
  }
  MiUnlockWorkingSetExclusive(&v7->Vm.Instance, v10);
  if( v4 < 0 )
    goto LABEL_22;
  if( v6 )
    v4 = PsChargeProcessNonPagedPoolQuota(ProcessToCharge, v6);
  if( v4 < 0 )
  {
LABEL_22:
    if( v5 )
    {
      do
      {
        v17 = (_MMCLONE_DESCRIPTOR *)v5->CloneNode.Children[0];
        ExFreePoolWithTag(v5, 0);
        v5 = v17;
      }
      while( v17 );
    }
    v5 = 0i64;
  }
  result = v4;
  *CloneChain = v5;
  return result;
}

Referenced by:

MiCloneProcessAddressSpace