首页
论坛
课程
招聘
雪    币: 1591
活跃值: 活跃值 (395)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝

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

2020-7-6 23:05 1972

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

2020-7-6 23:05
1972

0x0 前言

 

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


0x1  演示


          

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

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

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

0x2 原理


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

    他的内核内存标记如下:


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



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


0x3 简单代码实现

#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;

}


0x4 总结

          

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

[公告]SDC2020 看雪安全者开发者峰会10月23日将在上海举行!欢迎参加!

最新回复 (5)
雪    币: 72
活跃值: 活跃值 (93)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
实都 活跃值 2020-7-6 23:08
2
0
666 佳片频出
雪    币: 265
活跃值: 活跃值 (66)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
niuzuoquan 活跃值 2020-7-6 23:17
3
0
mark
雪    币: 191
活跃值: 活跃值 (33)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
hackflame 活跃值 2020-7-7 00:03
4
0
豆豆牛逼
雪    币: 256
活跃值: 活跃值 (151)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ZwCopyAll 活跃值 2020-7-7 07:11
5
0
666
雪    币: 1591
活跃值: 活跃值 (395)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
学技术打豆豆 活跃值 2020-7-7 08:45
6
0
hackflame 豆豆牛逼
火哥,玩笑了
游客
登录 | 注册 方可回帖
返回