MiSetSystemCodeProtection
NTSTATUS __stdcall MiSetSystemCodeProtection(
_KLDR_DATA_TABLE_ENTRY *DataTableEntry,
_MMPTE *FirstPte,
_MMPTE *EndPte,
UINT64 ProtectionMask){
unsigned int v6;
NTSTATUS v7;
__int64 v8;
unsigned int v9;
_MI_TB_FLUSH_LIST v10;
char *v11;
unsigned int SystemRegionType;
INT64 v13;
INT16 v14;
_MMSUPPORT_INSTANCE *SessionVm;
int v16;
_MMPTE *v17;
INT64 v19;
char v20;
UINT64 v21;
__int64 v22;
UINT64 v23;
UINT64 v24;
__int64 v25;
INT64 v26;
unsigned __int64 v27;
_MMPFN *v28;
_UNICODE_STRING *v29;
UINT8 v30;
PWCHAR v31;
int v32;
ULONG_PTR v33;
UINT64 v34;
_MMPTE v35;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v36;
__int64 v37;
__int64 v38;
NTSTATUS v39;
_MMPFN *v40;
unsigned __int64 v41;
unsigned __int64 v42;
__int64 v43;
unsigned __int64 v44;
unsigned __int64 v45;
unsigned __int64 v46;
int v47;
char v48;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v49;
int v50;
UINT64 WsIrql;
char WsIrqla;
__int64 v53;
_MMSUPPORT_INSTANCE *v54;
int v55;
INT64 v56;
_SUBSECTION *i;
char *v58;
UINT64 SpinCount;
_KLDR_DATA_TABLE_ENTRY *DataTableEntrya;
UINT64 PteOffset;
_MMPTE *v62;
_MMPFN *v63;
_CONTROL_AREA *ControlArea;
_MMPTE *v65;
_MI_TB_FLUSH_LIST TbFlushList[48];
v65 = EndPte;
DataTableEntrya = DataTableEntry;
PteOffset = 0i64;
v6 = ProtectionMask;
memset(TbFlushList, 0i64, 0xB8u);
v7 = 1;
if( v6 == 24 || (v6 & 0x10) == 0 )
{
v55 = 0;
}
else
{
v6 &= ~0x10u;
v55 = 1;
}
v8 = (__int64)(((_QWORD)FirstPte << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
if( !MI_IS_PHYSICAL_ADDRESS((VOID *)v8) )
{
v9 = v6;
v10 = 2;
if( v6 == 256 )
{
v11 = 0i64;
ControlArea = MiSectionControlArea((_SECTION *)DataTableEntrya->SectionPointer);
v62 = 0i64;
}
else
{
v62 = EndPte;
ControlArea = 0i64;
v9 = v6 & 0xFFFFFFFE;
v17 = EndPte;
if( (v6 & 5) != 5 )
v9 = v6;
v11 = 0i64;
if( MiMakeDriverPagesPrivate(DataTableEntrya, FirstPte, v17, (v9 >> 1) & 2, WsIrql) < 0 )
return 0;
}
SystemRegionType = MiGetSystemRegionType(v8);
if( SystemRegionType == 1 )
SessionVm = MiGetSessionVm(v13, 1i64, v14);
else
SessionVm = MiGetAnyMultiplexedVm(MiWorkingSetTypeSystemViews, (VOID *)SystemRegionType);
v54 = SessionVm;
*(_QWORD *)&TbFlushList[4] = 0i64;
if( v16 != 1 )
v10 = 0;
TbFlushList[2] = 20;
LOWORD(TbFlushList[1]) = 0;
TbFlushList[0] = v10;
v19 = (INT64)SessionVm;
*(_QWORD *)&TbFlushList[6] = 0i64;
v58 = 0i64;
MiLockWorkingSetShared();
WsIrqla = v20;
if( FirstPte <= v65 )
{
v21 = 0i64;
v22 = 0i64;
for( i = 0i64; ; v22 = (__int64)i )
{
if( !v11 )
goto LABEL_22;
if( ((unsigned __int16)FirstPte & 0xFFF) == 0 )
break;
LABEL_23:
if( FirstPte > v62 )
{
v23 = v8 - (unsigned __int64)DataTableEntrya->DllBase;
if( v22 )
{
v25 = *(_QWORD *)(v22 + 16);
i = (_SUBSECTION *)v25;
PteOffset = 0i64;
}
else
{
MiFlushTbList(TbFlushList);
MiUnlockPageTableInternal((INT64)v54, (UINT64)v11);
LOBYTE(v24) = WsIrqla;
MiUnlockWorkingSetShared(v54, v24);
i = MiOffsetToProtos(ControlArea, v23, &PteOffset);
MiLockWorkingSetShared();
MiLockPageTableInternal((INT64)v54, (UINT64)v11, 0i64);
v21 = PteOffset;
v25 = (__int64)i;
}
v9 = (*(unsigned __int16 *)(v25 + 32) >> 1) & 0x1F;
v62 = &FirstPte[*(unsigned int *)(v25 + 44) - (unsigned __int64)(*(_DWORD *)(v25 + 52) & 0x3FFFFFFF) - v21 - 1];
if( (v9 & 5) == 5 )
v9 &= ~1u;
}
LODWORD(v26) = MI_READ_PTE_LOCK_FREE((INT64)FirstPte);
v56 = v26;
if( (v26 & 1) != 0 )
{
LODWORD(v27) = MI_READ_PTE_LOCK_FREE((INT64)&v56);
v53 = (v27 >> 12) & 0xFFFFFFFFFi64;
v28 = &MmGetPfnDb()[v53];
LOBYTE(v32) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v28, v29, v30, v31);
v21 = 0i64;
if( v32 )
goto LABEL_77;
if( (MiGetPagePrivilege(v33, 0i64, 0i64) & 0x40) != 0 )
{
if( (v6 & 6) != 0 )
goto LABEL_33;
}
else if( (MiFlags & 0x10000) != 0 && (v6 & 4) != 0 && (((unsigned __int64)v28->u4._bf_0 >> 60) & 7) == 3 )
{
LABEL_33:
v11 = v58;
v7 = 0;
goto LABEL_34;
}
v35.u.Long = 0i64;
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v28->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v28->u2._bf_0 < 0 );
}
v28->OriginalPte.u.Long ^= (*((_DWORD *)&v28->3 + 4) ^ (32 * v9)) & 0x3E0;
if( v55 )
MiMarkPfnVerified(v28, 4ui64);
v63 = (_MMPFN *)(v56 & 0x42);
if( (v56 & 0x42) != 0 )
{
MiCaptureDirtyBitToPfn();
v35.u.Long = v36.Long;
}
_InterlockedAnd64(&v28->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v35.u.Long )
MiReleasePageFileInfo(
*(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v28->u4._bf_0 >> 39) & 0x3FF)),
v35,
1ui64);
LODWORD(v37) = MiMakeValidPte((_XSTATE_CONFIGURATION *)FirstPte, v53, v9);
v38 = v37;
if( (v9 & 5) == 4 && v63 )
v38 = v37 | 0x42;
MiWriteValidPteNewProtection((INT64 *)FirstPte, v38);
if( (MiFlags & 0x100) != 0 || (MiFlags & 0x200) != 0 )
{
v39 = MI_TIGHTER_PERMISSIONS((_MMPTE)v56, (_MMPTE)v38);
v21 = 0i64;
if( !v39 )
goto LABEL_77;
}
MiInsertTbFlushEntry(TbFlushList, (VOID *)v8, 1ui64, 0i64);
LABEL_76:
v21 = 0i64;
goto LABEL_77;
}
if( (v26 & 0x400) != 0 )
goto LABEL_76;
v21 = 0i64;
if( (v26 & 0x800) != 0 )
{
v40 = MiLockTransitionLeafPage((ULONG_PTR)FirstPte, 0i64);
v21 = 0i64;
if( !v40 )
goto LABEL_78;
LODWORD(v41) = MI_READ_PTE_LOCK_FREE((INT64)FirstPte);
v42 = v41;
if( *(&stru_140C4DB30 + 42) )
{
if( (v41 & 0x10) != 0 )
v42 = v41 & 0xFFFFFFFFFFFFFFEFui64;
else
v42 = v41 & ~*(&stru_140C4DB30 + 42);
}
v63 = &MmGetPfnDb()[(v42 >> 12) & 0xFFFFFFFFFi64];
v43 = 32i64 * (v9 & 0x1F);
v44 = v43 | v41 & 0xFFFFFFFFFFFFFC1Fui64;
v45 = v63->OriginalPte.u.Long & 0xFFFFFFFFFFFFFC1Fui64;
v56 = v44;
v46 = v44;
v63->OriginalPte.u.Long = v43 | v45;
LOBYTE(v47) = MiPteInShadowRange((UINT64)FirstPte);
v21 = 0i64;
if( v47 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v44 & 1) != 0 )
v46 = v44 | 0x8000000000000000ui64;
FirstPte->u.Long = v46;
_InterlockedAnd64(&v63->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
}
else if( v26 && v6 != 256 )
{
v48 = v26 ^ (v26 ^ (32 * v9)) & 0xE0;
v56 = v26 ^ ((unsigned __int16)v26 ^ (unsigned __int16)(32 * v9)) & 0x3E0;
v49.Long = v56;
LOBYTE(v50) = MiPteInShadowRange((UINT64)FirstPte);
v21 = 0i64;
if( v50 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v48 & 1) != 0 )
v49.Long |= 0x8000000000000000ui64;
FirstPte->u.Long = v49.Long;
}
LABEL_77:
++FirstPte;
v8 += 4096i64;
LABEL_78:
v11 = v58;
if( FirstPte > v65 )
goto LABEL_34;
v19 = (INT64)v54;
}
MiFlushTbList(TbFlushList);
MiUnlockPageTableInternal(v19, (UINT64)v11);
LABEL_22:
v11 = (char *)MmGetPteBase() + (((unsigned __int64)FirstPte >> 9) & 0x7FFFFFFFF8i64);
v58 = v11;
MiLockPageTableInternal(v19, (UINT64)v11, 0i64);
v22 = (__int64)i;
v21 = 0i64;
goto LABEL_23;
}
LABEL_34:
MiFlushTbList(TbFlushList);
if( v11 )
MiUnlockPageTableInternal((INT64)v54, (UINT64)v11);
LOBYTE(v34) = WsIrqla;
MiUnlockWorkingSetShared(v54, v34);
}
return v7;
}Referenced by:
MiProtectSystemImage
MiSetImageProtection