不同选项下的虚拟内存分布
Linux系统下,ELF格式的可执行文件的各个段都会被分配到不同的虚拟内存空间中。在操作系统实现地址随机化机制(Address Space Layout Randomization)之前,程序在任意一次执行下,所使用的虚拟空间的地址往往是相同的。这就给恶意攻击者的攻击行为提供了很大的便利(见Stack Smashing for Fun and Profit)。以下述程序为例。
#include <stdio.h>
int local_global_var=0x10;
int local_global_func(void)
{
return 0x40;
}
int main(void)
{
int x = local_global_func();
local_global_var= 0x20;
while(getchar()!= 'q')
continue;
return0;
}
图1示例程序exam1.c
程序包括一个全局函数,一个全局变量和一个局部变量。程序中的while语句等待用户的输入,当输入字符为'q'时程序终止,这是为了方便在程序运行时观察不同的段所对应的不同内存。通过使用不同的编译选项,来观察它们对程序的虚拟内存的影响。选项分为3种情况:1)不使用任何特殊选项;2)使用-fpic选项。该选项通常被用来生成与位置无关动态库文件;3)-fpie选项,用于生成位置无关的代码段。
不使用任何特殊选项
不使用任何选项的情况下,在程序运行过程中,通过Linux命令cat /proc/pidnum/maps来输出程序的虚拟内存分布状况。其中pidnum是程序的进程号,通过ps命令获得。程序的两次不同执行下,其虚拟内存的分布如图2所示。
图中显示,程序exam1的代码段和数据段分别对应的虚拟地址为00400000-00401000和00600000-00601000,而且在两次不同的执行中,地址不变。堆栈段(stack)在两次执行中则有了变化,第一次为