avatar

Catalog
线性地址的管理

前言

本篇开始,进一步学习与物理页相关的内存管理知识。关于页的知识,在介绍段、页时已学习过一部分基础,可以参考以下链接:

进程空间的地址划分

进程空间地址的划分这个我们已经比较熟悉了,以x86为例,就是对4GB内存空间的划分,可以参考下面两张图:

说明:

  • 线性地址有4GB,但未必都能访问。这个之前也学习过,由于一些地址没有挂物理页,因此无法访问
  • 有些地址可以访问,有些不能访问,有些具有特定权限才能访问,这些性质都需要被记录,那么Windows系统是如何分配,管理这些内存的呢?这就本篇要学习的主题,线性地址的管理。

内核空间的地址管理

内核空间,也就是我们常说的高2G,内核空间的地址是通过链表串起来的,遍历链表便可以找到各片地址的属性。之所以使用链表,主要是依据不同进程的高2G地址往往是相同的,因此高2G的地址变化较少,使用链表足矣。相比之下,用户空间的地址管理就较为复杂,这也是本篇主要讨论的内容。

用户空间的地址管理

搜索二叉树

与内核空间的地址使用链表串起来所不同的是,用户空间的地址通过一颗搜索二叉树来记录。它里面的每一个节点都记录了一块被占用的线性地址空间。

在Windows XP(32位)系统中任意打开一个进程,本篇以打开Dbgview为例。

找到Dbgview对应的EPROCESS结构体,定位到+0x11c处,有一个VadRoot成员,这个成员就是记录当前进程线性地址空间的搜索二叉树。其对应的地址,则是二叉树根节点的地址。

_MMVAD

_MMVAD是搜索二叉树节点的数据类型,根据MMVAD中的成员(ReactOS与Xp有所不同),可以对这个节点所对应的线性地址区域有个整体上的认识,以根节点为例:

这里介绍部分本篇中涉及到的成员:

  • StartingVpn:当前节点对应的内存的线性地址起始位置(以页为单位),本例中为0xab0000。
  • EndingVpn:当前节点对应的内存的线程地址结束位置(以页为单位),本例中为0xab0000。说明当前节点对应的内存大小为1个物理页,从线性地址0xab0000开始到线性地址0xab0fff结束。
  • Parent:父节点地址,本例中根节点没有父节点,所以为空。
  • LeftChild:左子树地址。
  • RightChild:右子树地址。
  • u:用于标识内存属性。
  • ControlArea:控制区域。

在知道左子树或右子树地址后,就可以通过

Code
1
kd> dt _MMVWAD 0x????????(左子树或右子树地址)

一层一层找到所有的节点,不过这样就略显麻烦了,因此Windbg提供了一个指令

Code
1
kd> !vad 0x????????(进程根节点地址)

通常运行该指令,就可以列出所指进程内线性地址的记录情况。

_CONTROL_AREA

根据列出的二叉树的内容,除了Start、End这种前面介绍的用于描述线性地址区间的属性,还有Level记录了当前节点位于二叉树的层数(depth),还有一些属性会逐个进行介绍,这一部分,介绍Private/Mapped这一列。

在介绍MMVAD时,它内部有一个ControlArea成员,这个成员也是一个结构体,以根节点为例:

这里需要关注的是FilePointer字段,当这个值为空的时候,这块内存是private类型,也就是进程自己VirutalAlloc申请出来的内存。

如果FilePointer这个字段不为空,则这块内存是mapped类型,也就是说它映射了其它类型(dll, exe, nls等)的文件到内存中。此时FilePointer会指向一个_FILE_OBJECT文件对象结构,这个文件对象结构可以看到被映射文件的相关描述性信息。

_MMVAD_FLAGS

_MMVAD中有一个成员u,其实指的是一个union共同体,这个共同体结构如下:

c
1
2
3
4
union {
ULONG_PTR LongFlags;
MMVAD_FLAGS VadFlags; //通常只使用这个成员
}u;

尽管有两个成员,通常来说,只使用VadFlags这个成员。其结构如下:

这里主要介绍几个比较重要的字段:

  • CommitCharge:最大可提供物理页的数目。

  • ImageMap:若值为1,则说明是映射(Mapped)了镜像文件(通常是.exe),若为0则不是。

  • Protection:表示当前_MMVAD节点描述的内存块的属性,取值如下:

    Code
    1
    2
    3
    //1:READONLY	2:EXECUTE	3:EXECUTE _READ	
    //4:READWRITE 5:WRITECOPY 6:EXECUTE_READWRITE
    //7:EXECUTE_WRITECOPY

总结

本篇,主要对用户空间的地址管理及其相关结构的进行简要介绍,部分结构的关系可以参考下图:

部分没有介绍到的,会在之后的篇章再作讨论。

参考资料

参考书籍:

  • 《Windows内核原理与实现》p243 —— 潘爱民

参考教程:

  • 海哥逆向中级预习班课程

参考链接:

Author: cataLoc
Link: http://cataloc.gitee.io/blog/2020/08/30/%E7%BA%BF%E6%80%A7%E5%9C%B0%E5%9D%80%E7%9A%84%E7%AE%A1%E7%90%86/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶