MiPrepareToHotPatchImage
NTSTATUS __stdcall MiPrepareToHotPatchImage(INT64 a1, UINT64 *a2, UINT64 a3){
INT64 v3;
unsigned __int8 v6;
_RTL_BITMAP *Pool;
_RTL_BITMAP *v8;
NTSTATUS v9;
unsigned int *v10;
_RTL_BITMAP *v11;
int *v12;
UINT64 *v13;
int v14;
__int64 v15;
unsigned int v16;
unsigned int v17;
unsigned int v18;
VOID *v19;
const VOID *v20;
_RTL_BITMAP *v21;
_RTL_BITMAP *v22;
INT64 v23;
UINT64 i;
int v25;
unsigned int NextForwardRunClear;
unsigned int v27;
int v28;
__int64 v29;
int BitMapHeader;
INT64 v32;
INT64 v33;
int v34[2];
int *v35;
__int128 v36;
INT64 v37;
INT64 v38[19];
INT64 v40;
unsigned __int8 v41;
v40 = a3;
v3 = a3;
v36 = 0i64;
memset(v38, 0i64, 0x60u);
if( v3 )
{
v6 = 0;
}
else
{
v3 = (INT64)v38;
v40 = (INT64)v38;
v6 = 1;
}
v41 = v6;
Pool = (_RTL_BITMAP *)MiAllocatePool(
256i64,
8 * ((unsigned int)((*(_DWORD *)(a1 + 32) & 0x3F000) != 0) + 2 + (*(_DWORD *)(a1 + 32) >> 18)),
0x20206D4Dui64);
v8 = Pool;
*(_QWORD *)(a1 + 48) = Pool;
if( Pool )
{
Pool->SizeOfBitMap = *(_DWORD *)(a1 + 32) >> 12;
Pool->Buffer = &Pool[1].SizeOfBitMap;
v8 = *(_RTL_BITMAP **)(a1 + 48);
}
if( !v8 )
return -1073741670;
RtlSetAllBits(v8);
v10 = (unsigned int *)(v3 + 32);
v37 = v3 + 32;
*(_DWORD *)(a1 + 36) = 8 * *(_DWORD *)(v3 + 32);
if( !a2 )
{
v11 = (_RTL_BITMAP *)MiAllocatePool(64i64, 8 * (((*v10 & 0x3F) != 0) + 2 + (*v10 >> 6)), 0x20206D4Dui64);
*(_QWORD *)(a1 + 40) = v11;
if( v11 )
{
v11->SizeOfBitMap = *v10;
v11->Buffer = &v11[1].SizeOfBitMap;
v11 = *(_RTL_BITMAP **)(a1 + 40);
}
if( !v11 )
return -1073741670;
RtlClearAllBits(v11);
MiProcessHotPatchUndoTable(a1, v3);
v12 = 0i64;
v13 = a2;
goto LABEL_34;
}
v35 = (int *)((char *)a2 + *((unsigned int *)RtlFindHotPatchBase(a2) + 6));
v34[0] = 0;
v9 = RtlCountRequiredHotPatchAddressTableEntries(
*(_QWORD *)(a1 + 8),
*(_DWORD *)(a1 + 32),
*(_DWORD *)(a1 + 32) + v14,
a2,
v35,
v6,
BitMapHeader,
v32,
v34);
v34[1] = v9;
if( v9 < 0 )
return v9;
v16 = *v10;
if( v34[0] )
{
v17 = v16 + v34[0];
*(_DWORD *)(a1 + 36) = 8 * (v16 + v34[0]);
v15 = ((8 * v17) >> 12) + (((8 * v17) & 0xFFF) != 0);
LODWORD(v40) = v15;
v18 = *(_DWORD *)(v3 + 36);
if( (unsigned int)v15 > v18 )
{
if( 8 * v17 + *(_DWORD *)(a1 + 32) > ((*(unsigned int *)(*(_QWORD *)a1 + 28i64) | ((unsigned __int64)*(unsigned __int8 *)(*(_QWORD *)a1 + 33i64) << 32))
- (*(unsigned int *)(*(_QWORD *)a1 + 24i64) | ((unsigned __int64)*(unsigned __int8 *)(*(_QWORD *)a1 + 32i64) << 32))
+ 1) << 12 )
return -1073741671;
v9 = MiCommitHotPatchTable(*(_QWORD *)a1, *(_QWORD *)(a1 + 24) + (v18 << 12), (unsigned int)v15 - v18);
if( v9 < 0 )
return v9;
*(_DWORD *)(v3 + 36) = v40;
}
}
else
{
v17 = *v10;
}
if( !v6 )
{
if( v17 > *v10 )
{
v19 = MiAllocatePool(256i64, 6 * v17, 0x48555048ui64);
v40 = (INT64)v19;
if( !v19 )
return v9;
v20 = *(const VOID **)(v3 + 40);
if( v20 )
{
memmove(v19, v20, 6 * *v10);
ExFreePoolWithTag(*(PVOID *)(v3 + 40), 0);
v19 = (VOID *)v40;
}
*(_QWORD *)(v3 + 40) = v19;
}
v21 = (_RTL_BITMAP *)MiAllocatePool(64i64, 8 * ((v17 >> 6) + ((v17 & 0x3F) != 0) + 2), 0x20206D4Dui64);
v22 = v21;
*(_QWORD *)(a1 + 40) = v21;
if( v21 )
{
v21->SizeOfBitMap = v17;
v21->Buffer = &v21[1].SizeOfBitMap;
v22 = *(_RTL_BITMAP **)(a1 + 40);
}
if( !v22 )
return -1073741670;
RtlClearAllBits(v22);
MiProcessHotPatchUndoTable(a1, v3);
}
if( !*(_DWORD *)(a1 + 36)
|| (v9 = MiPrepareImagePagesForHotPatch(
(INT64 *)a1,
*(_QWORD *)(a1 + 24),
(*(_DWORD *)(a1 + 36) >> 12) + (unsigned int)((*(_DWORD *)(a1 + 36) & 0xFFF) != 0)),
v9 >= 0) )
{
*(_QWORD *)&v36 = a1;
*((_QWORD *)&v36 + 1) = v6;
v12 = v35;
v13 = a2;
RtlEnumerateHotPatchPatches(a2, (unsigned int *)v35, v15, &v36);
LABEL_34:
if( !v6 )
{
if( !RtlCheckCurrentPatchesApplied(*(_QWORD *)(a1 + 8), *(_QWORD *)(a1 + 24), *(UINT64 **)(v3 + 40), *v10) )
return -1073740628;
LOBYTE(v40) = 0;
RtlHotPatchSynchronizationRequired(
*(_QWORD *)(a1 + 8),
(INT64)v13,
(INT64)v12,
v23,
*(_QWORD *)(a1 + 24),
*(_QWORD *)(v3 + 40),
*(PRTL_BITMAP *)(a1 + 40),
v32,
v33,
(INT64)&v40);
RtlClearAllBits(*(PRTL_BITMAP *)(a1 + 40));
if( (_BYTE)v40 )
*(_DWORD *)(a1 + 136) |= 1u;
}
LODWORD(v40) = 0;
for( i = 0i64; ; i = v27 + v25 )
{
NextForwardRunClear = RtlFindNextForwardRunClear(*(_QWORD *)(a1 + 48), i, (UINT64 *)&v40);
v27 = NextForwardRunClear;
if( !NextForwardRunClear )
break;
v25 = v40;
v9 = MiPrepareImagePagesForHotPatch(
(INT64 *)a1,
*(_QWORD *)(a1 + 8) + (unsigned int)((_DWORD)v40 << 12),
NextForwardRunClear);
if( v9 < 0 )
return v9;
LODWORD(v40) = v27 + v25;
}
MiMapHotPatchImageInSystemSpace();
v9 = v28;
if( v28 >= 0 )
{
v29 = *(_QWORD *)(*(_QWORD *)(a1 + 64) + 24i64);
*(_QWORD *)(a1 + 72) = v29;
*(_QWORD *)(a1 + 80) = v29 + *(unsigned int *)(a1 + 32);
return 0;
}
}
return v9;
}Referenced by:
MiPerformImageHotPatch