係統粉 > IT資訊 > 微軟資訊

簡單看一下 微軟新出的內核頁表隔離補丁

發布時間:2018-01-09    瀏覽數:

簡單看一下 微軟新出的內核頁表隔離補丁(1)

相比以往的內核多了一套用戶層專用的頁表,裏麵沒有內核內存的映射(除了幾個r3進r0的入口)

KiEnableKvaShadowing由KiInitializeBootStructures和KxInitializeProcessorState調用,應該隻初始化一次

signed __int64 __fastcall KiEnableKvaShadowing(__int64 a1, __int64 a2)

{

__int64 v3; // rdx@3

__int64 v4; // rcx@3

__int64 v5; // r8@3

char v6; // al@4

signed __int64 v7; // r9@8

signed __int64 v8; // r10@8

signed __int64 v9; // rdx@8

signed __int64 v10; // rcx@10

unsigned __int64 v15; // rax@14

__int64 v16; // rdx@15

signed __int64 result; // rax@21

_RBX = a1;

if ( !(unsigned __int8)KiIsKvaShadowDisabled() )

{

if ( (unsigned __int8)KiIsKvaLeakSimulated() )

{

v6 = 1;

KiKvaLeakageSimulate = 1;

}

else

{

v6 = KiKvaLeakageSimulate;

}

if ( !KiKvaLeakage && !v6 )

return 1i64;

*(_QWORD *)(v4 + 28288) = __readcr3();

v7 = v3 + 4132;

v8 = 7i64;

*(_QWORD *)(v3 + 4216) = *(_QWORD *)(v3 + 4100);

*(_QWORD *)(v3 + 4100) = v3 + 16896;

v9 = v3 + 17376;

do

{

if ( *(_QWORD *)v7 )

{

v10 = *(_QWORD *)v7 - 32i64;

*(_QWORD *)v9 = _RBX - 384;

*(_QWORD *)(v9 + 8) = v10;

*(_QWORD *)v10 = v9;

*(_QWORD *)v7 = v9;

}

v9 += 512i64;

v7 += 8i64;

--v8;

}

while ( v8 );

if ( *(_DWORD *)(_RBX + 36) )

{

result = KiShadowProcessorAllocation(_RBX, v5);

if ( !(_DWORD)result )

return result;

*(_DWORD *)(_RBX + 28312) |= 2u;

goto LABEL_23;

}

KiInitializeIdt(v5, 1);

*(_BYTE *)(*(_QWORD *)(*MK_FP(__GS__, 392i64) + 184i64) + 703i64) = 1;

byte_1403BFBFF = 1;

KiSetAddressPolicy(_CF, _ZF, _SF, _OF, 1);

if ( *(_QWORD *)(_RBX + 25192) & 0x40000000000i64 )

{

v15 = __readcr4() & 0xFFFFFFFFFFFFFF7Fui64;

_bittestandset(&v15, 0x11u);

__writecr4(v15);

__writecr3(__readcr3() | 2);

KiFlushPcid = 1;

}

HvlRescindEnlightenments(0x40000000000i64, -129i64);

KiKvaShadow = 1;

if ( KiFlushPcid )

{

if ( *(_BYTE *)(_RBX + 1597) != 1 )

{

LABEL_20:

KiKvaShadowMode = 1;

LABEL_23:

if ( KiFlushPcid )

__asm { lock bts qword ptr [rbx+6E80h], 3Fh }

return 1i64;

}

}

else if ( *(_BYTE *)(_RBX + 1597) != 1 )

{

KiKvaShadowMode = 2;

return 1i64;

}

__writecr4(v16 & __readcr4());

goto LABEL_20;

}

KiIsKvaShadowConfigDisabled = 1;

return 1i64;

}

關鍵代碼

signed __int64 __fastcall KiShadowProcessorAllocation(__int64 a1, __int64 a2)

{

__int64 v2; // rsi@1

__int64 v3; // rdi@1

signed int v5; // ebx@4

__int64 v6; // rax@6

__int64 v7; // rax@6

unsigned int v8; // edx@6

v2 = a2;

v3 = a1;

if ( !KiKvaShadow )

return 1i64;

if ( MmCreateShadowMapping(a2, 20480i64) )

{

v5 = 0;

if ( MmCreateShadowMapping(v3 + 28288, 4096i64) )

{

v5 = 1;

if ( *(_DWORD *)(v3 + 36) )

return 1i64;

LODWORD(v6) = RtlImageNtHeader(0x140000000i64);

LODWORD(v7) = RtlSectionTableFromVirtualAddress(

v6,

0x140000000i64,

(unsigned int)KiDivideErrorFaultShadow - 0x40000000);

v8 = *(_DWORD *)(v7 + 16);

if ( *(_DWORD *)(v7 + 8) > v8 )

v8 = *(_DWORD *)(v7 + 8);

if ( MmCreateShadowMapping(*(_DWORD *)(v7 + 12) + 0x140000000i64, (v8 + 4095) & 0xFFFFF000) )

return 1i64;

}

MmDeleteShadowMapping(v2, 20480i64);

if ( v5 )

MmDeleteShadowMapping(v3 + 28288, 4096i64);

}

return 0i64;

}

似乎是把KiDivideErrorFaultShadow 所在的section這幾塊內核內存單獨拿出來創建了映射

剛好這一塊都是idt和syscall/sysenter的入口,在KVASCODE 這個section裏

簡單看一下 微軟新出的內核頁表隔離補丁(2)

當然IDT要用shadow的那份

KiInitializeIdt(v5, TRUE);

第二個參數應該就是是否使用shadow idt

然後根據cpu是否有flushpcid功能(KiFlushPcid)選擇shadow的方式KiKvaShadowMode = 1 or 2?

然後看一下sysenter的入口,內核頁表應該是被放在了gs:7000h裏麵,太簡單了不做分析,jmp後的流程和以前老Systemcall是一樣的

簡單看一下 微軟新出的內核頁表隔離補丁(3)

網絡異常 取消 重新上傳

隨便挑了個中斷分析了下

簡單看一下 微軟新出的內核頁表隔離補丁(4)

網絡異常 取消 重新上傳

然後是AttachProcess的時候也加了一些特技(以前就一句writecr3)

簡單看一下 微軟新出的內核頁表隔離補丁(5)

網絡異常 取消 重新上傳

void __fastcall KiLoadDirectoryTableBase(PEPROCESS ProcessObj, unsigned __int64 DirTableBase)

{

unsigned __int64 NewCr3; // rbx@1

unsigned __int64 v3; // rax@2

bool v4; // zf@2

bool v5; // sf@2

unsigned __int64 v6; // rcx@10

unsigned __int64 v7; // rax@11

NewCr3 = DirTableBase;

if ( KiKvaShadow )

{

v3 = DirTableBase;

v4 = (DirTableBase & 2) == 0;

v5 = (DirTableBase & 2 & 0x80u) != 0i64;

if ( DirTableBase & 2 )

{

v3 = DirTableBase | 0x8000000000000000ui64;

v4 = (DirTableBase | 0x8000000000000000ui64) == 0;

v5 = ((DirTableBase | 0x8000000000000000ui64) & 0x8000000000000000ui64) != 0i64;

}

*MK_FP(__GS__, 28672i64) = v3;

KiSetAddressPolicy(0, v4, v5, 0, ProcessObj->Pcb.AddressPolicy);

}

if ( HvlEnlightenments & 1 )

HvlSwitchVirtualAddressSpace(NewCr3);

else

__writecr3(NewCr3);

if ( KiKvaShadow && !KiFlushPcid )

{

v6 = __readcr4();

if ( v6 & 0x20080 )

{

v7 = v6;

_bittestandcomplement(&v7, 7u);

__writecr4(v7);

__writecr4(v6);

}

else

{

__writecr3(__readcr3());

}

}

}

頁表還是EPROCESS裏那個頁表,隻不過看起來是把KvaShadow暫時禁用了(不然一切換cr3 內核地址空間全沒了 直接炸穿)

Detach的時候也是直接調用的KiLoadDriectoryTableBase,被內聯了

簡單看一下 微軟新出的內核頁表隔離補丁(6)

網絡異常 取消 重新上傳

作者:看雪論壇 hzqst

原文鏈接:https://bbs.pediy.com/thread-223805.htm

上一篇:蘋果微軟Alphabet之後 亞馬遜市值也超過了6000億美元 下一篇:疑似整合破裂? 多個OEM廠商宣布將發布搭載亞馬遜Alexa的Win10 PC

相關資訊

最新熱門應用

電腦問答