首页
社区
课程
招聘
[原创]彩蛋解密之物理内存读写到****的转变
发表于: 2019-8-19 04:18 12185

[原创]彩蛋解密之物理内存读写到****的转变

2019-8-19 04:18
12185

通过查阅资料我们发现驱动层的代码不会出现在PML4T表的前0x80项中的,这样等于我们就有了0x80*(0x1000/8)*1G=65536G的空间是可以用来映射物理内存的

这里我们决定使用1G的大页面映射方式进行映射,我们的代码中只对前512G进行了映射,基本上现在内存没有超过这个大小的了。

https://github.com/zouxianyu/PhysicalMemoryRW

(别想了,这只是原料,反应需要自己实现的)

传送门:驱动层代码隐藏执行(有码)https://bbs.pediy.com/thread-253677.htm
在上次的文章结尾处我挖了个坑,这次给它填上。

令人挠头的操作:

首先放上一段在DriverEntry中让人看了挠头的操作
ContextVirtualToPhysical(&g_PhysicalOpCR3);
ULONG64 Read1 = *(PULONG64)0x0;
MyPrint(_TitleAndFunc "ReadTest1:%16IX\n", Read1);
ContextPhysicalToVirtual(&g_PhysicalOpCR3);
啊,读空指针啊,这不明摆着蓝屏吗?

唉,咋没蓝屏,还读到东西了呢?
下面我们来windbg看一下

唉,有点东西是吧

咋实现的啊,我先去看看代码吧:


咋看不懂呢

使用windbg简单分析:


这有个cr3,看看是啥东西?
这一堆整整齐齐的都是啥玩意啊?
不管了直接!vtop看一看
我相信看到这里,对分页机制比较熟悉的大手子们就应该大概懂实现原理了
首先放上一段在DriverEntry中让人看了挠头的操作
ContextVirtualToPhysical(&g_PhysicalOpCR3);
ULONG64 Read1 = *(PULONG64)0x0;
MyPrint(_TitleAndFunc "ReadTest1:%16IX\n", Read1);
ContextPhysicalToVirtual(&g_PhysicalOpCR3);
啊,读空指针啊,这不明摆着蓝屏吗?
ContextVirtualToPhysical(&g_PhysicalOpCR3);
ULONG64 Read1 = *(PULONG64)0x0;
MyPrint(_TitleAndFunc "ReadTest1:%16IX\n", Read1);
ContextPhysicalToVirtual(&g_PhysicalOpCR3);
啊,读空指针啊,这不明摆着蓝屏吗?

唉,咋没蓝屏,还读到东西了呢?
下面我们来windbg看一下

唉,有点东西是吧


咋看不懂呢

这有个cr3,看看是啥东西?
这一堆整整齐齐的都是啥玩意啊?
不管了直接!vtop看一看
我相信看到这里,对分页机制比较熟悉的大手子们就应该大概懂实现原理了
首先需要熟悉分页机制,不懂的查阅intel手册和网上的一些文章进行学习。
下面贴出intel手册中对于分页使用规则的详细说明。

调用CreatePhysicalOpCR3BySystemCR3进行初始化
在其中分别依次调用pAllocPhysicalOpPageTableMemory、pMapSystemPML4T、pFillGeneratedPML4TandPDPT进行初始化,并填充结构

需要读取物理内存时调用ContextVirtualToPhysical、ContextPhysicalToVirtual进行环境切换

卸载时调用FreePhysicalOpCR3
在其中依次调用pUnmapSystemPML4T、pFreePhysicalOpPageTableMemory并清理结构
首先使用:CreatePhysicalOpCR3BySystemCR3
进行初始化工作,下面是这个函数的代码
NTSTATUS CreatePhysicalOpCR3BySystemCR3(ULONG64 SystemCR3, PPHYSICAL_OP_CR3 pPhysicalOpCR3)
{
	//check the init state
	if (g_IsPhysicalOpInit)
		return STATUS_UNSUCCESSFUL;


	//allocate page table memory and fill the structure
	if (!NT_SUCCESS(pAllocPhysicalOpPageTableMemory(pPhysicalOpCR3)))
		return STATUS_UNSUCCESSFUL;

	//map pSystemPML4T to virtual address and fill the structure
	if (!NT_SUCCESS(pMapSystemPML4T(SystemCR3, pPhysicalOpCR3)))
		return STATUS_UNSUCCESSFUL;

	//fill PML4T and PDPT page table
	if (!NT_SUCCESS(pFillGeneratedPML4TandPDPT(pPhysicalOpCR3)))
		return STATUS_UNSUCCESSFUL;

	//generate new cr3 for reading the physical memory and add cr3 flag
	ULONG64	SystemCR3Flag = GetCR3Flag(SystemCR3);
	pPhysicalOpCR3->CR3Generated = (ULONG64)pPhysicalOpCR3->pAllocPA_PML4T | SystemCR3Flag;

	//fill the structure part:CR3System
	pPhysicalOpCR3->CR3System = SystemCR3;

	//print structure
	pPrintPhysicalOpStructure(pPhysicalOpCR3);

	g_IsPhysicalOpInit = TRUE;
	return STATUS_SUCCESS;
}

NTSTATUS CreatePhysicalOpCR3BySystemCR3(ULONG64 SystemCR3, PPHYSICAL_OP_CR3 pPhysicalOpCR3)
{
	//check the init state
	if (g_IsPhysicalOpInit)
		return STATUS_UNSUCCESSFUL;


	//allocate page table memory and fill the structure
	if (!NT_SUCCESS(pAllocPhysicalOpPageTableMemory(pPhysicalOpCR3)))
		return STATUS_UNSUCCESSFUL;

	//map pSystemPML4T to virtual address and fill the structure
	if (!NT_SUCCESS(pMapSystemPML4T(SystemCR3, pPhysicalOpCR3)))
		return STATUS_UNSUCCESSFUL;

	//fill PML4T and PDPT page table
	if (!NT_SUCCESS(pFillGeneratedPML4TandPDPT(pPhysicalOpCR3)))
		return STATUS_UNSUCCESSFUL;

	//generate new cr3 for reading the physical memory and add cr3 flag
	ULONG64	SystemCR3Flag = GetCR3Flag(SystemCR3);
	pPhysicalOpCR3->CR3Generated = (ULONG64)pPhysicalOpCR3->pAllocPA_PML4T | SystemCR3Flag;

	//fill the structure part:CR3System
	pPhysicalOpCR3->CR3System = SystemCR3;

	//print structure
	pPrintPhysicalOpStructure(pPhysicalOpCR3);

	g_IsPhysicalOpInit = TRUE;
	return STATUS_SUCCESS;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (18)
雪    币: 6664
活跃值: (957)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
来个沙发,顺便问句,虚拟机支持刷tlbs吗?
2019-8-19 06:47
0
雪    币: 914
活跃值: (2463)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
3
你这不是沉迷编程,而是沉迷如何当个大手子
2019-8-19 08:35
1
雪    币: 711
活跃值: (253)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
带手子来支持一下
2019-8-19 08:58
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
5
给力嗷
2019-8-19 10:38
0
雪    币: 4061
活跃值: (3452)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
最近帖子都那么活泼吗? 又get到一波表情包
2019-8-19 11:39
0
雪    币: 4057
活跃值: (312)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
7
2019-8-19 11:40
0
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
8
搞了个半天自己实现了一个不稳定版的MmMapIoSpace,意义何在
2019-8-19 11:57
0
雪    币: 5270
活跃值: (3505)
能力值: ( LV7,RANK:117 )
在线值:
发帖
回帖
粉丝
9
kingswb 来个沙发,顺便问句,虚拟机支持刷tlbs吗?
是要做啥?没看懂
2019-8-19 11:58
0
雪    币: 5270
活跃值: (3505)
能力值: ( LV7,RANK:117 )
在线值:
发帖
回帖
粉丝
10
hzqst 搞了个半天自己实现了一个不稳定版的MmMapIoSpace,意义何在
重点在结尾,没细说的那部分
2019-8-19 11:59
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
11
刚才没细看,细看了一下,我评价一下,首先你这个帖子的确很少见,过程讲的也不错,但是没有太大的意义,如果只是用来研究的话,的确可以,因为系统本身的物理内存映射方法也不只有这一种,而且这种读写方式有弊端,如果分页内存换出,你的这个读写就毫无用处了,分页内存换回的机制是触发异常以后才会换回来,这个坑以前我就踩过,目前还真的没有解决方法
2019-8-19 12:45
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
12
也不是说不能拿来用,只能说。。。。不得劲
2019-8-19 12:48
0
雪    币: 5270
活跃值: (3505)
能力值: ( LV7,RANK:117 )
在线值:
发帖
回帖
粉丝
13
对,据我了解换出的话需要用缺页isr中的某些函数处理一下
2019-8-19 13:38
0
雪    币: 5270
活跃值: (3505)
能力值: ( LV7,RANK:117 )
在线值:
发帖
回帖
粉丝
14
如果忽略缺页问题的话,那么这种方案移植到应用层会是很好玩的
2019-8-19 13:44
0
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
15
鬼才zxy 对,据我了解换出的话需要用缺页isr中的某些函数处理一下
访问一下虚拟内存就回来了,但是这种方式读写的话做不到
2019-8-19 14:02
0
雪    币: 36
活跃值: (1061)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
mark
2019-8-19 14:46
0
雪    币: 6664
活跃值: (957)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
鬼才zxy 是要做啥?没看懂
没什么,就是隐藏执行的话使用两张pte表,就行。一个读写,一个执行。就是需要刷tbls,虚拟机好像不行,我不确定,特此求问
2019-8-19 18:17
0
雪    币: 5270
活跃值: (3505)
能力值: ( LV7,RANK:117 )
在线值:
发帖
回帖
粉丝
18
kingswb 没什么,就是隐藏执行的话使用两张pte表,就行。一个读写,一个执行。就是需要刷tbls,虚拟机好像不行,我不确定,特此求问[em_12]
stlb了解一下,现在的cpu微架构不支持这种分离了
2019-8-19 19:44
0
雪    币: 259
活跃值: (283)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
学习
2019-8-21 10:52
0
游客
登录 | 注册 方可回帖
返回
//