
相比以往的内核多了一套用户层专用的页表,里面没有内核内存的映射(除了几个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里

当然IDT要用shadow的那份
KiInitializeIdt(v5, TRUE);
第二个参数应该就是是否使用shadow idt
然后根据cpu是否有flushpcid功能(KiFlushPcid)选择shadow的方式KiKvaShadowMode = 1 or 2?
然后看一下sysenter的入口,内核页表应该是被放在了gs:7000h里面,太简单了不做分析,jmp后的流程和以前老Systemcall是一样的

网络异常 取消 重新上传
随便挑了个中断分析了下

网络异常 取消 重新上传
然后是AttachProcess的时候也加了一些特技(以前就一句writecr3)

网络异常 取消 重新上传
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,被内联了

网络异常 取消 重新上传
作者:看雪论坛 hzqst
原文链接:https://bbs.pediy.com/thread-223805.htm
相关资讯
最新热门应用
非小号交易平台官网安卓版
其它软件292.97MB
下载
币交易所地址
其它软件274.98M
下载
iotx交易所app
其它软件14.54 MB
下载
zt交易所安卓最新版
其它软件273.2 MB
下载
币拓交易所bittok
其它软件288.1 MB
下载
u币交易所平台app
其它软件292.97MB
下载
热币全球交易所app官网版
其它软件287.27 MB
下载
多比交易平台app
其它软件28.28MB
下载
币赢交易所app官网安卓版
其它软件14.78MB
下载
toncoin币交易所安卓版
其它软件48MB
下载