0x0 前言
Windows10的新功能内存分区,这两天感兴趣想了解一下,加上逆向360VT已接近尾声,所以今天抽出一点时间来学习,网上未找到相关资料,导致下面的分析仅是个人观点,用来抛转引玉,如有错误,请多指教,逆的时间很短,所以请当入门来了解。
0x1 基础介绍
内存分区是物理页的集合,这些物理页基本上独立于其他分区中的物理页进行管理。
每个内存分区都抽象为一个分区对象,可以通过句柄进行访问。一个内存分区是内置的。
在对象命名空间中,它是KernelObjects\MemoryPartition0:这是系统内存分区。
在32位Windows中,这个系统分区是唯一的内存分区。64位下可以自由创建自已的内存分区。
0x2 系统内存分区创建过程
1.在PspInitPhase0 创建内存分区对象类型PsPartitionType。
2。在PspInitializeSystemPartitionPhase0创建系统分区:全局变量PspSystemPartition,结构体:_EPARTITION
其中会创建三个重要的结构(名字是根据我的想法随意写的):
MmPartition:基本内存分区
CcPartition : 文件缓存分区
ExPartition : Executive分区
1。EPARTITION.MmPartition(基本内存分区)对应结构体_MI_PARTITION,全局变量:MiSystemPartition与之对应。
创建的API:MmCreatePartition(_EPARTITION *PartitionObject, char ID)//MiInitializePartition(_MI_PARTITION *MmPartition, int16 PartitionId)等
通过逆向得知,MmPartition分区是可以有多个存在的,他们存在一个数组里,通过Index来选择,可以通过Eprocess->Vm->Instance->PartitionId来当索引 ,也可以通过FileObject,也可以通过缓存等等条件来进行选择,总共有416个函数都调用了这个数组来进行选择,如果你想玩点骚操作,这里可能是你们关注的重点。
找到这个数组最简单的办法是找:MiPartitionIdToPointer这个函数
下面看的会更直观点。
所以可以自行创建很多个基本内存分区,例如以下我创建了一个,并且将进程PartitionId改为2,这里的id号因为windows设计的原因,需要是偶数。
目前我比较关心的代码在MiInitializePartition(_MI_PARTITION *MmPartition, int16 PartitionId)里面,这里面初始化了以下各种链表。:
只截了很小的一部份,请自行逆向。
用WINDBG查看:
但以上的划分,会涉及更多细分的地方,例如Total不等于0,但FLINK和BLINK=0xFFFFFFFF。
如:ListName=ModifiedPageList修改链表,他就分为:【预留和未预留】等等之类。
当然里面涉及到更多的物理页的数据,很多查询函数最终都是调用的这个结构体里的数据。
例如工作集的初始化等,内容非常多,请各位自行逆向,这对于win10没有符号的情况下,后期逆向内存是非常有益。
0x3 创建新内存分区代码(卸载内存分区代码请自行完善)
#include <ntddk.h>
typedef NTSTATUS (*ZWCREATEPARTITION)(
HANDLE ParentPartitionHandle,
HANDLE *PartitionHandle,
ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes);
PHANDLE PartitionHandle;
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
pDriverObject->DriverUnload = DriverUnload;
UNICODE_STRING DestinationString;
RtlInitUnicodeString(&DestinationString, L"ZwCreatePartition");
ZWCREATEPARTITION ZwCreatePartition = MmGetSystemRoutineAddress(&DestinationString);
OBJECT_ATTRIBUTES ObjectAttributes;
RtlInitUnicodeString(&DestinationString, L"\\KernelObjects\\MemoryPartition1");
ObjectAttributes.RootDirectory = 0;
ObjectAttributes.SecurityQualityOfService = 0;
ObjectAttributes.ObjectName = &DestinationString;
ObjectAttributes.Length = 0x30;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.Attributes = 0x200;
NTSTATUS status= ZwCreatePartition(NULL, &PartitionHandle, 0x1f0003, &ObjectAttributes);
return STATUS_SUCCESS;
}
下面的内存分区数据和上面的数据不同,是因为已经重启了再截的图,所以数据产生了变化。
0x4 结语
CcPartition和ExPartition的初始化非常简单,可以自行逆向,由于今天逆向的时间有限,借此贴抛砖引玉,希望各位能玩出更多的骚操作,睡觉!
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法