win10 1909逆向(反向计算windows内核内存布局及代码实现)
2020-07-08 17:15:40 Author: bbs.pediy.com(查看原文) 阅读量:328 收藏

活跃值: 活跃值 (329)

能力值:

( LV3,RANK:30 )

在线值:

[原创]win10 1909逆向(反向计算windows内核内存布局及代码实现)

1天前 720

[原创]win10 1909逆向(反向计算windows内核内存布局及代码实现)

          在最新的windows版本中,内存动态并且很多在32位下的变量符号,windbg下如今都没有了,变成了类似qword_1404687D8这样的东东,对于逆向内存的同学来说,非常不便,但是Windows为了提高效率来进行地址判断的前提下还是给我们留下了一条门缝,我们可以利用此机制反向推导出一些重要的内存布局。

          

注1:最下面的两个地址是特意申请的两个地址,分别是非分页内存和分页内存地址,用来和上面的基址来比较。

注2:MMPFNDATABASE的基址对比正确。

注3:MiVaProcessSpace 是动态内核虚拟地址空间。

     windows在内存设计之初,设计了一个内核Mark标记,从0xFFFF8000 0000 0000起一直标记了0x100个的标记,这里被微软根据特定的位算法进行了特别的划分(代码演示)。

    他的内核内存标记如下:

那这些数字代表什么意义了?微软其实已经定了一个枚举类型来详细记录:

那通过这两个我们就可以反推出我们需要的内存布局(有些内存布局在这里无法得到,是因为有额外的处理流程,可以通过别的方法得到)

#include <ntddk.h>

#define NameSize 0x10
#define MiVaUnused 0
#define MiVaSessionSpace 1
#define MiVaProcessSpace 2
#define MiVaBootLoaded 3
#define MiVaPfnDatabase 4
#define MiVaNonPagedPool 5
#define MiVaPagedPool 6
#define MiVaSpecialPoolPaged 7
#define MiVaSystemCache 8
#define MiVaSystemPtes 9
#define MiVaHal 10
#define MiVaSessionGlobalSpace 11
#define MiVaDriverImages 12
#define MiVaSystemPtesLarge 13
#define MiVaKernelStacks 14
#define MiVaMaximumType 15

PCHAR TypeName[NameSize] =
{
	"MiVaUnused",
	"MiVaSessionSpace",
	"MiVaProcessSpace",
	"MiVaBootLoaded",
	"MiVaPfnDatabase",
	"MiVaNonPagedPool",
	"MiVaPagedPool",
	"MiVaSpecialPoolPaged",
	"MiVaSystemCache",
	"MiVaSystemPtes",
	"MiVaHal",
	"MiVaSessionGlobalSpace",
	"MiVaDriverImages",
	"MiVaSystemPtesLarge",
	"MiVaKernelStacks",
	"MiVaMaximumType"
};

PVOID FindBase();
PVOID FindSystemKernenlRegion(PVOID pMark);
PVOID FindBaseRegion(PVOID pMark, UCHAR Type);
VOID Unload(PDRIVER_OBJECT pDriverObject)
{

	KdPrint(("end\n"));

}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
	
	KdPrint(("start\n"));
	pDriverObject->DriverUnload = Unload;
	//第一步找到Mark地址
	PVOID pMarkAddr = FindBase();
	//第二步开始解析
	FindSystemKernenlRegion(pMarkAddr);
	PVOID NonPool = ExAllocatePoolWithTag(NonPagedPool, 0x1000, 'NonP');
	PVOID Pool = ExAllocatePoolWithTag(PagedPool, 0x1000, 'ionP');
	KdPrint(("NonPagePool=%llx", NonPool));
	KdPrint(("PagePool=%llx", Pool));

	ExFreePool(NonPool);
	ExFreePool(Pool);



	return STATUS_SUCCESS;
}

PVOID FindBase()
{
	UNICODE_STRING FuncName;
	RtlInitUnicodeString(&FuncName, L"ExAcquirePushLockExclusiveEx");
	PVOID FuncAddr=MmGetSystemRoutineAddress(&FuncName);
	PUCHAR var = (PUCHAR)FuncAddr;
	for (int i = 0; i < 0x100; i++)
	{
		if (*var == 0x48 && *(var+3)==0x27)
		{
			
			return var+(*(PUINT32)(var - 4));
			
		}
		
		var++;
	}
	return 0;
}
PVOID FindSystemKernenlRegion(PVOID pMark)
{
	PVOID Region = 0;
	

	for (int i = 0; i < 0x10; i++)
	{
		KdPrint(("%s=%llx\n", TypeName[i], FindBaseRegion(pMark, i)));
	}

}
PVOID FindBaseRegion(PVOID pMark,UCHAR Type)
{
	PUCHAR var = pMark;
	UINT64 pBaseAddr = 0x100;
	//
	for (int i = 0; i < 0x100; i++)
	{
		if (*(var) == Type)
		{
			pBaseAddr =((pBaseAddr | i) << 0x27 | 0xFFFF000000000000);
			return pBaseAddr;
			
		}
		var++;
	}
	return 0;

}

         可以利用点很多,希望能让大家了解一些Windows的内存机制,以后共同学习。


文章来源: https://bbs.pediy.com/thread-260527.htm
如有侵权请联系:admin#unsafe.sh