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