-
-
[原创]win10 1909逆向(0E号异常---1.主动触发页面支撑的内存区)
-
2021-4-6 15:13
8831
-
[原创]win10 1909逆向(0E号异常---1.主动触发页面支撑的内存区)
0x0 前言
这里是完成上一篇文章《win10 1909逆向(内存区对象(SectionObject)----1.页面支撑的内存区)》的实现部分,了解共享内存映射后,windows是如何通过0E号异常完成物理页的挂靠和管理,因为0E号异常过于庞大,和上一篇一样,将分支剪掉,将判断过程忽略掉,仅保留最核心的关键部分。
0x1 代码触发
首先在映射完成后下一个中断,这样进入Windbg里面,我们bp 到swapgs的下面的地址,因为是共享内存,PTE是没有值的,直接g运行。
0x2 逆向跟踪
进入 KiPageFaultShadow和KiPageFault,这里的主要目的是用来填充KTRAP_FRAME,然后进入MmAccessFault:
进入KiPageFault
中断进入过程中,0E号异常会有相应的错误码,我们这里的ErrorCode是为6,下面是错误码的解释。( 用户模式 | 写),在用户模式下的写操作引起的异常。
进入MmAccessFault:
1.创建一个结构体,并进行相应的初始化:
struct _FAULTCONTEXT
{
PVOID VirtualAddress;
UINT64 ErrorCode;
PKTRAP_FRAME pTrapFrame;
PVOID PointerPte;
PVOID PointerPde;
PVOID PointerPpe;
PVOID PointerPxe;
PVOID pProcessVm;
UINT32 U9Low;
char irql;
char u9flags;
PVOID U10;
char Flags;
PVOID Vad;
PVOID ProtoPTE;
PVOID U14;
PVOID U15;
PVOID U16;
PVOID U17;
};
这里如果是DPC等级进入换页,会有条件蓝屏。
如果VirtualAddress < 0xFFFF800000000000进入MiUserFault(pFaultContext)
1.判断PPE是否有效。
2判断PDE是否有效。
3.修改PDE的属性为:*PDE | 0x1000000000000020
4.MiZeroFault。主要实现:1.寻找虚拟地址的VAD。2.MiGetProtoPteAddress 得到原型PTE的地址。
5.返回0xC0000016。
进入MiDispatchFault:
MiResolveProtoPteFault(FaultContext, __int64 a2, _QWORD *a3)
1。将PTE的值改成 ffffffff00000490
这里就要简单介绍一下,基于VAD的PTE:
这里是由Windows实现的。当PTE值为空(_MMPTE.u.Long=0)时,必须检查虚拟地址描述符(VAD)进程,当设置_MMPTE.u.Soft.Prototype标志并且PTE.u.Proto.ProtoAddress等于0xFFFFFFFF0000时(在Windows中,该状态称为虚拟地址描述符);
2。MiCreateSharedZeroPages 主要是创建一个物理页,并且设置好属性,用来放进FirstPrototypePte里,但这时,PTE目前还是0xFFFFFFFF00000490
3。最后调用MiCompleteProtoPteFault进入属性值的判断和修改,并最终挂入PTE。
0x3 完成
整体写的会非常简单,但实际内部的判断条件非常苛刻和复杂,会涉及很多工作集的处理,这里全部简化,只为大家了解最基本的流程,如果有兴趣,各位可以自行逆向,接下来会逆向最为复杂的文件映射。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法