前言
我们如果想要实现进程隐藏在3环通常会使用到PEB断链去达到隐藏进程的效果,但是那只是表面上的进程隐藏,所有内存的详细信息都会被储存在vad树里面,这里我们就来探究在64位下如何隐藏可执行内存
vad
VAD是管理虚拟内存的,每一个进程有自己单独的一个VAD树,使用VirtualAlloc
申请一个内存,则会在VAD树上增加一个结点,其是_MMVAD
结构体
dt _MMVAD
image-20220329154007738.png
这里找一个进程,因为是根节点所以没有父节点
image-20220329154131189.png
然后往左遍历二叉树,在下一个节点处的父节点指向了上一个二叉树
image-20220329154230061.png
注意StartingVpn
和EndingVpn
这两个结构,描述了当前页的位置,以4kb为单位,即0x400000到0x488000这一块内存空间已经被占用了
image-20220329154654585.png
在0x18有一个ControlArea
结构,描述了这块结构体到底被谁占用,这里跟进去看0x24有一个FilePointer
结构,如果这里的值为0就是一个真正的物理页,如果有值继续往里面找
image-20220329155005328.png
这里对应了Dbgview.exe
image-20220329155328329.png
在操作系统里面分配的内存只可能有两种类型,一种是VirtualAlloc
自己分配的内存,一种是文件映射使用CreateFileMapping
的内存,当ControlArea
的FilePointer
值为空的时候则是我们自己用VirtualAlloc
分配的内存,还没有对应,如果值不为空则是文件映射的内存
分页机制
在32位里面有2-9-9-12
、10-10-12
两种分页模式,而在64位下只有一种分页模式,即9-9-9-9-12
分页模式
随着计算机技术的发展,64位系统逐渐占据主流地位,那么也就表示CPU的最大寻址范围为64位。但实际上,CPU只使用了其中的48位用于寻址,并使用9-9-9-9-12
分页模式。即便如此,在未来较长一段时间里,48位寻址范围也足够大部分人的日常使用了
9-9-9-9-12
分页表示物理地址拥有四级页表,在Intel开发手册中,将这四级页表分别称为PML4E
、PDPTE
、PDE
、PTE
,但微软的命名方式略有不同,将这四级页表分别称为PXE
、PPE
、PDE
、PTE
,WinDbg
中也是如此
image-20220504165636253.png
启用分页模式条件:cr0.PG = 1
且 cr0.PE = 1
根据不同CPU架构及特性主要分为三种模式,处于哪种模式视寄存器属性不同:
-
• 32-bit paging(32位OS):
cr0.PG = 1
、cr4.PAE = 0
-
• PAE paging(32位OS且开启了PAE):
cr0.PG = 1
、cr4.PAE = 1
、IA32_EFER.LME = 0
-
• IA-32e paging(64位OS):
cr0.PG = 1
、cr4.PAE = 1
、IA32_EFER.LME = 1
需要注意的是:
-
1. 32bit下,每个entry(表项)是4字节大小;而在PAE和IA-32e下,每个entry是8字节大小
-
2. 在x64体系中只实现了48位的
virtual address
,高16位被用作符号扩展,这高16位要么全是0,要么全是1。所以在讨论64bit地址的时候,高16位不使用
我们主要研究的是IA-32e
模式下的内存,这里IA-32e
提供了三种页转换模型:
-
• 4k:PML4t,PDPT,PDT和PT
-
• 2M:PML4T,PDPT和PDT
-
• 1G