MiRelocateImage
__int64 __fastcall MiRelocateImage(__int64 a1, __int64 a2, unsigned int a3, int a4, __int64 a5, int a6){
unsigned int v10;
int v11;
__int64 v12;
unsigned int v13;
__int64 v14;
__int64 v15;
UINT64 v16;
char v17;
unsigned int v18;
unsigned __int64 v19;
__int16 v20;
unsigned int v21;
unsigned int v22;
__int64 v23;
size_t v24;
UINT64 v25;
CHAR *v26;
UINT64 v27;
CHAR *v28;
INT64 v29;
int Config;
UINT64 v31;
INT64 v32;
int v33;
unsigned __int64 v34;
_QWORD *v35;
__int64 v36;
unsigned int v37;
unsigned int v38;
unsigned __int64 v39;
unsigned int v40;
UINT64 v41;
unsigned int v42;
unsigned int v43;
unsigned int v44;
__int64 *v45;
__int64 v46;
INT64 v47;
__int64 v48;
__int64 v49;
unsigned int v50;
unsigned int v52;
unsigned int v53;
unsigned __int64 v54;
unsigned __int64 v55;
unsigned int v56;
unsigned __int16 v57;
_WORD *v58;
unsigned int v59;
__int64 v60;
unsigned int v61;
__int64 v62;
unsigned int v63;
unsigned int i;
unsigned __int64 v65;
int v66;
_QWORD *v67;
UINT64 v68;
_MI_PARTITION *ControlAreaPartition;
UINT64 v70;
volatile INT64 *v71;
INT64 v72;
unsigned int v73;
unsigned int v74;
unsigned int v75;
int v76;
INT64 v78;
_QWORD *v79;
unsigned int v80;
INT64 v82;
__int64 v83;
_ETHREAD *CurrentThread;
int v85;
unsigned int v86;
unsigned __int64 v87;
unsigned int v88;
CHAR *v89;
unsigned int v91;
size_t Size;
unsigned int Sizea;
UINT64 v94;
INT64 a2a;
UINT64 PteOffset[3];
INT64 v97;
__int64 v98;
__int64 v99;
unsigned __int64 v100;
INT64 result[2];
int v102;
memset((INT64)result, 0i64);
v94 = 0i64;
v10 = 2;
v99 = *(_QWORD *)(a1 + 56);
if( (unsigned int)MiLegacyImageArchitecture(*(_WORD *)(v99 + 48)) )
{
v10 = v11 + 34;
if( (*(_BYTE *)(v12 + 44) & 1) != 0 )
return 0i64;
v13 = (*(_WORD *)(v12 + 46) & 0x1000) != 0 ? 0xC000007B : 0;
}
else
{
v13 = -1073741701;
}
v14 = *(unsigned int *)(a2 + 88);
LODWORD(v94) = v14;
v15 = *(unsigned int *)(a2 + 92);
v75 = *(_DWORD *)(a2 + 92);
HIDWORD(v94) = v75;
if( (_DWORD)v14 )
{
if( !(_DWORD)v15 )
return v13;
}
else
{
if( (_DWORD)v15 )
return v13;
v10 &= ~2u;
}
if( (*(_BYTE *)(a1 + 15) & 1) != 0 )
return 0i64;
v16 = *(_QWORD *)a1;
PteOffset[2] = v16;
v98 = *(_QWORD *)(v16 + 96);
v17 = *(_BYTE *)(a1 + 14) & 0x40;
if( (a3 & 0xFFF) > (v17 != 0 ? 4092 : 4088) || ((v17 != 0 ? 3 : 7) & a3) != 0 )
return v13;
v18 = a3 | 1;
if( !v17 )
v18 = a3;
v73 = v18;
v19 = *(_QWORD *)(a1 + 32);
v87 = v19;
if( v10 >= 0x20 && !a4 )
{
v20 = *(_WORD *)(v12 + 46);
if( (v20 & 0x40) == 0 && MmRegistryState != -1 && (v20 & 0x1000) == 0 )
return 0i64;
}
v21 = *(_DWORD *)(a1 + 8);
v22 = v21;
v80 = v21;
if( (v10 & 2) == 0 )
{
v22 = (v18 >> 12) + 1;
v80 = v22;
}
v91 = v21 << 12;
if( (int)v15 + (int)v14 > v21 << 12 )
return v13;
if( (v10 & 2) != 0 )
{
if( (int)v15 + (int)v14 <= (unsigned int)v14 )
return v13;
v23 = v14;
if( v14 + v19 <= v19 )
return v13;
}
else
{
v23 = v14;
}
if( (v10 & 2) != 0 && v23 + v15 + v19 <= v19 )
return v13;
Size = 8i64 * v22;
v24 = Size + v15 + 112;
a2a = 0i64;
v82 = 0i64;
v76 = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
LODWORD(v25) = MiAllocatePool((struct _SLIST_ENTRY *)0x100);
v26 = (CHAR *)v25;
PteOffset[1] = v25;
if( !v25 )
return 3221225626i64;
v27 = v25;
do
v27 += 4096i64;
while( v27 < v25 + v24 );
*(_BYTE *)(v25 + 68) = 0;
*(_QWORD *)(v25 + 56) = v80;
*(_QWORD *)(v25 + 24) = 0i64;
if( (v10 & 2) == 0 )
{
v29 = v25 + 72;
LABEL_28:
Config = MiSelectImageBase(a1, (__int64)v26, a4, a6, &a2a);
if( Config < 0 )
{
MiFreeImageLoadConfig(v29);
ExFreePoolWithTag(v26, 0);
if( !a4 )
Config = v13;
goto LABEL_70;
}
v31 = v29;
v32 = a2a;
v97 = a2a;
MiUpdateCfgSystemWideBitmap(v16, a2a, v31);
Config = v33;
if( v33 < 0 )
goto LABEL_155;
*((_DWORD *)v26 + 16) = v73;
*((_QWORD *)v26 + 5) = v32 - v87;
v34 = a5 - v87;
if( a5 == -1 )
v34 = 0i64;
*((_QWORD *)v26 + 6) = v34;
v89 = v26 + 112;
*(_QWORD *)v26 = v26 + 112;
memset((INT64)(v26 + 112), 0i64);
v35 = v26 + 112;
v78 = (INT64)&v26[Size + 112];
*((_QWORD *)v26 + 4) = v78;
v10 |= 4u;
if( (v10 & 2) == 0 )
{
LABEL_56:
v35[(unsigned __int64)*((unsigned int *)v26 + 16) >> 12] |= 1ui64;
if( (*(_DWORD *)(v16 + 56) & 0x40000000) != 0 )
{
v60 = 0i64;
v61 = 0;
v79 = 0i64;
v62 = *(_QWORD *)(a1 + 64);
v83 = v62;
v63 = *((_DWORD *)v26 + 14);
if( v80 <= v63 )
v63 = v80;
for( i = 0; i < v63; v89 += 8 )
{
if( *v35 != v60 || MiDoesPageRequireRetpolineFixups((INT64)(v26 + 72), i) )
{
v65 = MI_READ_PTE_LOCK_FREE(v62 + 8i64 * i);
v100 = v65;
if( (v65 & 0x400) != 0 )
{
*((_QWORD *)v26 + 13) = 0i64;
Config = -1073740023;
goto LABEL_69;
}
v60 = 0i64;
if( (v65 & 0x800) != 0 )
{
v66 = 1;
if( qword_140C4DC80 )
{
if( (v65 & 0x10) != 0 )
v65 &= ~0x10ui64;
else
v65 &= ~qword_140C4DC80;
}
v67 = (_QWORD *)((char *)MmGetPfnDb() + 48 * ((v65 >> 12) & 0xFFFFFFFFFi64));
if( (v67[2] & 0x400i64) != 0 && (*(_BYTE *)(MiGetSubsectionFromPte(v67[2]) + 34) & 2) != 0 )
v66 = v60;
if( v66 )
{
MiSetLeafPfnBuddy(v67, 0i64);
if( *((_QWORD *)v26 + 13) == v60 )
*((_QWORD *)v26 + 13) = v68;
else
MiSetLeafPfnBuddy(v79, v68);
v79 = (_QWORD *)v68;
++v61;
}
}
v62 = v83;
}
++i;
v35 = v89 + 8;
}
ControlAreaPartition = MiGetControlAreaPartition((_CONTROL_AREA *)v16);
v70 = v61;
if( !(unsigned int)MiChargeCommit(ControlAreaPartition, v61, 0i64) )
{
*((_QWORD *)v26 + 13) = 0i64;
Config = -1073741670;
goto LABEL_69;
}
v46 = (__int64)CurrentThread;
--*((_WORD *)CurrentThread + 243);
v71 = (volatile INT64 *)(a1 + 40);
ExAcquirePushLockExclusiveEx(a1 + 40, 0i64);
MiUpdateControlAreaCommitCount(v16, v70);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 40), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(v71);
KeAbPostRelease((PVOID)v71);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
v47 = a2a;
}
else
{
v46 = (__int64)CurrentThread;
v47 = v97;
}
LOBYTE(v10) = v10 | 8;
MI_LOCK_RELOCATIONS_EXCLUSIVE(v46, (__int64)v26);
v48 = v98;
*(_QWORD *)(v98 + 32) = v26;
*(_QWORD *)(a1 + 32) = v47;
v49 = v99;
*(_QWORD *)v99 += *((_QWORD *)v26 + 5);
*(_DWORD *)(v16 + 92) |= 0x400000u;
if( (*(_DWORD *)(v16 + 56) & 0x800) != 0 )
MiSetDeleteOnClose((_CONTROL_AREA *)v16, 0i64);
if( (MiFlags & 0x4000) == 0
|| (*(_DWORD *)(v16 + 92) & 0xC0000) == 0
|| (qword_140C1D940 ? (Config = qword_140C1D940(*(_QWORD *)(v48 + 40) & 0xFFFFFFFFFFFFFFF8ui64, v47)) : (Config = -1073741637),
Config >= 0) )
{
Config = 0;
v50 = a4 ? -1 : MmGetSessionIdEx(*((_QWORD *)KeGetCurrentThread() + 23));
if( a6 != 1 || *((_QWORD *)v26 + 12) )
{
if( (*(_DWORD *)(v16 + 56) & 0x40000000) != 0 )
{
MiWalkEntireImage(v16, 0i64, 8, v50);
if( (unsigned int)MiColdPageSizeSupported() )
MiMakeUnusedImageExtentsCold(v16);
}
Config = MiWalkEntireImage(v16, 0i64, 2, v50);
}
}
MI_UNLOCK_RELOCATIONS_EXCLUSIVE(v46, (__int64)v26);
if( Config >= 0 && !a6 )
*(_BYTE *)(v49 + 51) |= 4u;
LABEL_69:
if( (v10 & 8) != 0 )
goto LABEL_70;
LABEL_155:
MiFreeRelocations((_DWORD *)v16, v26);
goto LABEL_70;
}
memmove((UINT8 *)&v26[Size + 112], (UINT8 *)(v23 + v82), v75);
LODWORD(v23) = 0;
v36 = *((_QWORD *)v26 + 12);
if( v36 )
{
LODWORD(v23) = v102 & 0xFFFFF;
while( (_DWORD)v23 )
{
v23 = (unsigned int)(v23 - 1);
if( *(_QWORD *)(v36 + 8 * v23 + 56) )
goto LABEL_34;
}
LODWORD(v23) = 0;
}
LABEL_34:
v37 = v75;
v38 = 0;
if( v75 )
{
v39 = (unsigned __int64)&v26[Size + 112];
while( v37 >= 0xA )
{
v40 = *(_DWORD *)(v39 + 4);
v74 = v40;
if( v40 > v37 || (v40 & 1) != 0 || v40 < 8 )
goto LABEL_100;
v41 = *(unsigned int *)v39;
v85 = v41;
v42 = v10 & 0xFFFFFFFB;
if( (v41 & 0xFFF) == 0 )
v42 = v10;
v10 = v42;
if( (int)v41 + 4096 <= (unsigned int)v41 || (int)v41 + 4096 > v91 || (unsigned int)v41 < v38 )
goto LABEL_100;
if( v40 == 8 )
{
v37 -= 8;
v10 = v42 & 0xFFFFFFFB;
}
else
{
if( (MiFlags & 0x40000) != 0 && (*(_DWORD *)(v16 + 92) & 0xC0000) != 0 )
{
PteOffset[0] = 0i64;
if( (*((_BYTE *)MiOffsetToProtos((_CONTROL_AREA *)v16, v41, PteOffset) + 32) & 4) != 0 )
{
Config = -1073741701;
goto LABEL_69;
}
v40 = v74;
LODWORD(v41) = v85;
v39 = v78;
}
v86 = (unsigned int)v41 >> 12;
*(_QWORD *)&v26[8 * ((unsigned __int64)(unsigned int)v41 >> 12) + 112] |= v39;
v88 = (v41 & 0xFFFFF000) + 4096;
Sizea = v37 - v40;
Config = MiScanRelocationPage();
if( Config < 0 )
{
if( Config == -1073741207 )
{
Config = 0;
}
else if( Config == -1073741701 )
{
Config = v13;
}
goto LABEL_69;
}
v10 |= 0x10u;
v43 = v86;
if( v86 <= (unsigned int)v23 )
v43 = v23;
LODWORD(v23) = v43;
v37 = Sizea;
v40 = v74;
v38 = v88;
v39 = v78;
}
v39 += v40;
v78 = v39;
if( !v37 )
{
v44 = v75;
goto LABEL_53;
}
}
if( v37 != 8 )
goto LABEL_100;
v44 = v75 - 8;
}
else
{
v44 = 0;
}
LABEL_53:
MiUnmapImageInSystemSpace((INT64)result);
PsRevertToUserPagePriorityThread((__int64)CurrentThread, v76);
LOBYTE(v10) = v10 & 0xFE;
v45 = (__int64 *)*((_QWORD *)v26 + 2);
if( !v45 )
{
LABEL_54:
MiLogRelocationFaults(v16, (UINT64)&v94);
*((_QWORD *)v26 + 7) = (unsigned int)(v23 + 1);
if( (v10 & 0x14) == 20 )
{
v26 = MiCompressRelocations((INT64)v26, v44);
v35 = v26 + 112;
v89 = v26 + 112;
}
else
{
v35 = v26 + 112;
}
goto LABEL_56;
}
while( 1 )
{
v52 = v23;
v53 = *((_DWORD *)v45 + 3);
v54 = *(_QWORD *)&v26[8 * ((unsigned __int64)v53 >> 12) + 112];
LODWORD(v23) = v53 >> 12;
if( v53 >> 12 <= v52 )
LODWORD(v23) = v52;
if( v54 > 1 )
{
v55 = v54 & 0xFFFFFFFFFFFFFFFEui64;
v56 = *(_DWORD *)(v55 + 4) - 8;
v57 = v53 & 0xFFF;
v58 = (_WORD *)(v55 + 8);
v59 = v56 >> 1;
if( v59 )
break;
}
LABEL_92:
v45 = (__int64 *)*v45;
if( !v45 )
goto LABEL_54;
}
while( *v58 < 0x1000u || (unsigned __int16)(*v58 & 0xFFF) >= v57 )
{
++v58;
if( !--v59 )
goto LABEL_92;
}
LABEL_100:
Config = v13;
goto LABEL_69;
}
if( MiMapImageInSystemSpace(v16, 3, (__int64)result) < 0 )
{
ExFreePoolWithTag(v26, 0);
MiSetDeleteOnClose((_CONTROL_AREA *)v16, 0i64);
return 0i64;
}
v28 = (CHAR *)result[0];
v82 = result[0];
v76 = PsSetSystemPagePriorityThread((__int64)CurrentThread, 1);
v10 |= 1u;
v29 = (INT64)(v26 + 72);
Config = MiParseImageLoadConfig(v16, v28, (unsigned int)(v102 << 12), a2, v72, (INT64)(v26 + 72));
if( Config >= 0 )
goto LABEL_28;
ExFreePoolWithTag(v26, 0);
LABEL_70:
if( (v10 & 1) != 0 )
{
MiUnmapImageInSystemSpace((INT64)result);
PsRevertToUserPagePriorityThread((__int64)CurrentThread, v76);
}
return(unsigned int)Config;
}Referenced by:
MiGetSystemAddressForImage