32位linux内存空间布局(4GB)

在32位的系统中,计算机的寻址范围最大是4GB,也就是我们的程序有4GB可以使用,但是这4GB并不是全部给用户程序使用的。今天我们就来谈谈linux在32位系统下的内存布局。

     

 上图是在一个32位系统下的经典布局。注意这里的经典布局在后续是有变化的,并不是一成不变。后面我们会看到变化。图的最上方是高地址,下方是低地址。在Linux 系统在装载 elf 格式的程序文件时,会调用 loader 把可执行文件中的各个段依次载入到从某一地址开始的空间中。一般情况下是装载到0x8048000,windows平台下装载PE文件其实是有相似处的。了解过PE文件的知道在32位PE结构中基地址一般是0x4000000.有兴趣的可以了解下。这个装载地址并不是固定的,这取决于装载器和机器地址的位数。

       从下往上看,最先装载的是.test段,然后依次是.data段,.BSS段。test段其实就是代码段,放着可执行的一段程序。data段放的是已初始化的全局变量和静态变量。BSS段存放的是一个未初始化全局变量和静态变量的段,它在可执行文件或共享库中占据一段连续的内存空间。在程序加载到内存时,BSS段中的变量会被初始化为默认值(通常为零),并且该段的大小在可执行文件中是预留但不分配实际空间的。

     其实关于linux中一个程序是可以有很多段的,但这是最基本的3个段,可以参考elf文件格式来了解linux大致的一些段。从地址0~0xbffffff这3GB的空间是属于用户程序的。从这往上1GB是属于内核代码使用的。普通程序是无权访问到这个地址里的内容。但是通过一些特殊方法,例如系统调用是可以进入内核模式的。接着从图上看内核空间往下紧挨着是stack也就是我们熟识的栈,用于存放一些函数调用参数,局部变量,返回地址等重要信息的。Stack区域是唯一不需要映射,用户却可以访问的内存区域。栈是从高地址往低地址生长的。从图上可以看出。在这之后。栈和.BSS段之间是有一段空隙的。这段空间被分为两个部分,一个是mmap,一个是heap。mmap 是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,它是向上扩展的。heap就是我们熟知的堆。也就是可以动态扩展内存的区域,通常我们在C语言中调用malloc()函数来申请空间,就是在堆上进行的,看图我们也知道堆也是向高地址生长的。理解了这些基本概念。我们大致对内存空间的布局有了印象。但是细心的朋友会发现,这种布局有个弊端,mmap 区域与栈区域相对增长,这意味着堆只有 1GB 的虚拟地址空间可以使用,继续增长就会进入 mmap 映射区域,这是因为地址空间所限导致的。对于64位来说这种布局是完全够用的。因为空间足够大。所以32位有另外一种布局模式如下图:

经过修改,我们看到其实变化并不是很大,基本的内存布局还是一样,但是多了一些细节。下面我们就来探讨一下这些细节。首先我们看到mmap的扩展方向变了, 栈至顶向下扩展,并且栈是有界的。堆至底向上扩展,mmap 映射区域至顶向下扩展,mmap 映射区域和堆相对扩展,直至耗尽虚拟地址空间中的剩余区域,这种结构便于 C 运行时库使用 mmap 映射区域和堆进行内存分配。

      我们还看到在内核空间和栈空间中间有一段空隙。称之为Random stack offset.叫做栈随机偏移。因为栈是容易被攻击的。黑客在找到栈溢出的漏洞后需要精确知道栈上的布局和返回地址以便于覆盖自己填充的地址来劫持控制流。如果按照之前的布局,栈是固定不动的。现在留一段空隙,每次程序加载时,栈的基地址都是在这段空间随机的,这样黑客无法准确知道栈的起始位置和内存布局,加大漏洞利用的困难。下面两个Random offset道理是一样的就不再赘述。其实就是linux的安全机制中的地址随机化(ASLR)。RLIMMIT_STACK是Linux 操作系统中的资源限制常量,用于限制进程的栈大小。RLIMIT_STACK 是通过 setrlimit() 系统调用来设置和获取的。setrlimit() 可以用于设置进程的资源限制,包括栈大小。RLIMIT_STACK 的值可以是一个正整数,表示栈的最大尺寸,或者特定的常量值,如 RLIM_INFINITY 表示没有限制,或者 RLIM_SAVED_CURRLIM_SAVED_MAX 分别表示当前栈大小和最大栈大小的当前值,默认是8M,因为一个栈8M是完全够用的。但这个默认值可能会因不同的系统配置、内核版本和系统策略而有所不同。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值