MiUnloadSystemImage
VOID __stdcall MiUnloadSystemImage(PVOID ImageHandle, UINT64 UnloadFlags){
char v2;
bool v4;
char *v5;
unsigned __int64 v6;
_CONTROL_AREA *v7;
unsigned __int64 v8;
unsigned __int64 v9;
UINT64 v10;
POWER_SESSION_TIMEOUTS *v11;
unsigned int v12;
_LOAD_IMPORTS **v13;
__int64 v14;
int v15;
__int64 SessionVm;
MMPTE *PdeAddress;
_BOOL8 v18;
void *v19;
MMPTE *v20;
__int64 v21;
_MI_PARTITION *v22;
INT64 v23;
void *v24;
char v25;
char v26;
ULONG_PTR v27;
_CONTROL_AREA *v28;
CHAR *AnyMultiplexedVm;
int v30;
int v31;
_SECTION *v32;
void *v33;
void *v34;
UINT64 v35;
_CONTROL_AREA *v36;
INT64 v37;
MMPTE *v38;
unsigned int SessionId;
INT64 v40;
INT64 v41;
UINT64 NumberOfPtes;
_MMPTE *PointerPte;
UINT64 ExactPtes;
ULONG_PTR BugCheckParameter2;
__int64 v46;
INT64 v47[2];
__int64 v48;
INT64 a2[2];
__int128 v50;
__int128 v51;
INT64 result[26];
char v53;
int v54;
_SECTION *Object;
v53 = UnloadFlags;
v46 = 0i64;
v2 = UnloadFlags;
v48 = 0i64;
*(_OWORD *)v47 = 0i64;
memset((INT64)result, 0i64);
v4 = *((_QWORD *)ImageHandle + 17) == 1i64;
*(_OWORD *)a2 = 0i64;
v50 = 0i64;
v51 = 0i64;
if( v4 )
return;
v5 = (char *)*((_QWORD *)ImageHandle + 6);
BugCheckParameter2 = (ULONG_PTR)v5;
v6 = ((unsigned __int64)ImageHandle + 160) & -(__int64)((v2 & 4) != 0);
v7 = 0i64;
PointerPte = MiGetPteAddress(v5);
v8 = (unsigned __int64)*((unsigned int *)ImageHandle + 16) >> 12;
NumberOfPtes = v8;
Object = (_SECTION *)*((_QWORD *)ImageHandle + 14);
LOBYTE(v9) = MiBytesToMapSystemImage((_FAST_MUTEX *)*((unsigned int *)ImageHandle + 16));
ExactPtes = v9 >> 12;
if( (unsigned int)MiGetSystemRegionType((UINT64)v5) == 1 )
{
v54 = 0;
v13 = (_LOAD_IMPORTS **)MiSessionRemoveImage((UINT64)ImageHandle, (INT64)v47);
if( !v13 )
return;
v7 = MiSectionControlArea(Object);
if( *(_QWORD *)ImageHandle )
ExCovReadjustUnloadedModuleEntry((__int64)ImageHandle, 0);
v14 = *(_QWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1368i64);
v15 = v2 & 1;
if( v15 )
{
if( MiIsRetpolineEnabled() )
{
MiUnmapRetpolineStubs((INT64)ImageHandle, 0i64);
if( (unsigned int)MiIsImageFullyRetpolined((INT64)ImageHandle) )
KeFlushRsb();
_mm_lfence();
}
SessionVm = MiGetSessionVm();
MiDeleteSystemPagableVm(SessionVm, (__int64)v7, (unsigned __int64)PointerPte, NumberOfPtes, 3, a2);
}
MiReleaseSessionDriverCharges((INT64)v13);
if( v15 )
{
v18 = (dword_140C4C9F0 & 0xFFF) != 0;
if( v18 + ((unsigned int)dword_140C4C9F0 >> 12) )
MiUnmapPatchTable((UINT64)PointerPte + 8
* (ExactPtes - ((unsigned int)v18 + ((unsigned int)dword_140C4C9F0 >> 12))));
if( (*((_DWORD *)v7 + 14) & 0x4000000) != 0 )
{
SessionId = MmGetSessionIdEx(*((_QWORD *)KeGetCurrentThread() + 23));
MiDereferencePerSessionProtos((__int64 *)v7, SessionId);
}
MiGetPdeAddress(v5);
v19 = (void *)v47[0];
if( v47[0] )
v19 = (void *)(v47[0] + 1);
if( v19 )
MiGetPdeAddress(v19);
PdeAddress = MiGetPdeAddress(&v5[*((_DWORD *)ImageHandle + 16) - 1]);
if( v47[1] )
{
v38 = MiGetPdeAddress((PVOID)v47[1]);
if( v38 == PdeAddress )
PdeAddress = (MMPTE *)((char *)PdeAddress - 8);
}
if( PdeAddress >= v20 )
MiDeleteSessionPdes(v20, PdeAddress);
}
v21 = v48;
if( v48 )
{
LODWORD(v22) = MiPartitionIdToPointer(*(_WORD *)(v14 + 430), (UINT64)PdeAddress);
MiReturnCommit(v22, v21 - a2[1]);
_InterlockedExchangeAdd64((volatile signed __int64 *)(v14 + 48), -v21);
}
v2 = v53;
if( (v53 & 0x10) != 0 )
{
MiDereferenceImports(v13[11]);
MiFreeLoadedImportList(v13[11]);
}
ExFreePoolWithTag(v13, 0);
v12 = 0;
v8 = NumberOfPtes;
}
else
{
v12 = 1;
v54 = 1;
}
v4 = (*((_WORD *)ImageHandle + 54))-- == 1;
if( !v4 )
{
if( !v12 && (v2 & 2) != 0 )
VfDriverUnloadImage((_KLDR_DATA_TABLE_ENTRY *)ImageHandle);
return;
}
KeCleanupImageTracepoints((UINT64)ImageHandle, v10, v11);
if( (int)MiMarkKernelImageCfgBits((__int64)ImageHandle, 0i64) < 0 )
KeBugCheckEx(0x1Au, 0x1015ui64, (ULONG_PTR)v5, (ULONG_PTR)ImageHandle, (*(_DWORD *)(v6 + 36) >> 8) & 1);
if( v12 )
{
if( dword_140C4C9F0 )
MiClearDriverHotPatchPtes((INT64)ImageHandle);
}
else
{
MiDeleteSessionDriverProtos((__int64 *)v7);
}
if( MmHasImageBeenImportOptimized() )
MiFreeRetpolineImportInfo(v23);
if( MiIsRetpolineEnabled() )
{
if( v12 && !(unsigned int)MI_IS_PHYSICAL_ADDRESS(*((PVOID *)ImageHandle + 6)) )
MiUnmapRetpolineStubs((INT64)ImageHandle, v12);
MiMarkKernelImageRetpolineBits((INT64)ImageHandle);
if( (unsigned int)MiIsImageFullyRetpolined((INT64)ImageHandle) )
KeFlushRsb();
_mm_lfence();
}
if( v6 )
{
v24 = *(void **)(v6 + 136);
if( v24 )
{
MiFreeRetpolineRelocationInformation(v24);
*(_QWORD *)(v6 + 136) = 0i64;
}
}
if( (v2 & 2) != 0 )
{
VfDriverUnloadImage((_KLDR_DATA_TABLE_ENTRY *)ImageHandle);
KseDriverUnloadImage((__int64)ImageHandle);
}
if( !v12 )
{
MiReleasePrivilegedPtes();
v8 = 0i64;
NumberOfPtes = 0i64;
}
if( (v2 & 0x10) != 0 )
MiDereferenceImports(*((_LOAD_IMPORTS **)ImageHandle + 17));
MiFreeLoadedImportList(*((VOID **)ImageHandle + 17));
*((_QWORD *)ImageHandle + 17) = 1i64;
LdrUnloadAlternateResourceModule(v5);
if( (*((_DWORD *)ImageHandle + 26) & 0x100000) != 0 )
DbgUnLoadImageSymbolsUnicode((UNICODE_STRING *)((char *)ImageHandle + 88), v5, 0xFFFFFFFFui64);
if( *(_QWORD *)ImageHandle && v8 )
ExCovReadjustUnloadedModuleEntry((__int64)ImageHandle, 0);
v25 = 0;
v26 = 0;
if( !v8 || (v2 & 1) == 0 )
goto LABEL_94;
MiRememberUnloadedDriver((UNICODE_STRING *)((char *)ImageHandle + 88), v5, ExactPtes << 12);
v27 = 0i64;
if( Object )
{
v28 = MiSectionControlArea(Object);
v27 = (ULONG_PTR)v28;
if( *(_QWORD *)ImageHandle )
{
result[0] = (INT64)v28;
MiManageSubsectionView(result, v6, 4i64);
}
}
AnyMultiplexedVm = MiGetAnyMultiplexedVm(1i64);
if( (unsigned int)MI_IS_PHYSICAL_ADDRESS(v5) )
{
MiUnmapLargeDriver(v5, NumberOfPtes);
v25 = 1;
LABEL_94:
v32 = Object;
goto LABEL_63;
}
if( v6 )
MiUnlockDriverCode((__int64)ImageHandle);
qword_140C4CA60 = (UNICODE_STRING *)ImageHandle;
MiDeleteSystemPagableVm((__int64)AnyMultiplexedVm, v27, (unsigned __int64)PointerPte, NumberOfPtes, 5, a2);
v30 = DWORD2(v50);
v31 = a2[0];
if( v27 )
MiWalkEntireImage(v27, (unsigned __int64)&v46, 4, 0xFFFFFFFF);
qword_140C4CA60 = 0i64;
_InterlockedExchangeAdd((_DWORD *)&xmmword_140C4CA88 + 3, v31 - v30);
v32 = Object;
if( !Object )
{
MiReleasePrivilegedPtes();
if( !(unsigned int)MiCreateSystemWsles() )
{
v40 = MiVaToSoftwareWsle(
(INT64)AnyMultiplexedVm,
(__int64)((NumberOfPtes << 28) + ((_QWORD)PointerPte << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16);
if( ExactPtes != NumberOfPtes )
{
LOBYTE(v41) = 10;
memset(v40, v41);
}
}
v5 = (char *)BugCheckParameter2;
v26 = 1;
v25 = 0;
v2 = v53;
goto LABEL_94;
}
v5 = (char *)BugCheckParameter2;
v25 = 0;
v2 = v53;
LABEL_63:
if( v54 == 1 )
{
if( v32 )
MiReleasePrivilegedPtes();
if( (v2 & 1) != 0 )
MiReturnSystemImageCommitment(ImageHandle, (INT64)a2);
}
if( *(_QWORD *)ImageHandle )
MiProcessLoaderEntry((__int64 *)ImageHandle, 0);
if( v26 )
MiReleaseDriverPtes(0i64, PointerPte, (unsigned int)ExactPtes);
v33 = (void *)*((_QWORD *)ImageHandle + 10);
if( v33 )
ExFreePoolWithTag(v33, 0);
if( v6 )
{
v34 = *(void **)(v6 + 128);
if( v34 )
MiFreePatchTableProtos(v34);
}
if( Object )
{
if( v6 )
{
v35 = *(_QWORD *)(v6 + 56);
if( v35 )
MiReturnResident((INT64)&MiSystemPartition, v35);
}
v36 = MiSectionControlArea(Object);
v37 = (INT64)v36;
if( !v25 && v5 != *(char **)(*(_QWORD *)v36 + 32i64) )
{
MiFreePrivateFixupEntryForSystemImage(v5, 1ui64);
MiReturnSystemImageAddress(v5, *((unsigned int *)ImageHandle + 16));
}
if( v6 && v54 && (*(_DWORD *)(v6 + 36) & 0x80u) != 0 )
MiReturnCrossPartitionControlAreaCharges(v37);
MiDereferenceControlArea(v37);
ObDereferenceObjectDeferDelete(Object);
}
ExFreePoolWithTag(ImageHandle, 0);
}Referenced by:
MiApplyHotPatchToLoadedDriver
MiDereferenceImports
MmChangeImageProtection
MmLoadSystemImageEx
MmUnloadSystemImage