为了防止入侵者通过缓冲区溢出进行攻击,linux系统实现了栈随机化技术。
如下代码用于打印出main函数局部变量的地址:
#include <stdio.h>
int main()
{
int local;
printf("local at %p\n", &local);
sleep(-1);
return0;
}
gcc -O1 -m32 -o stack_main stack_main.c
[root@bogon asm]# ./stack_main &
[1] 6129
[root@bogon asm]# local at 0xbffc2fa0
[root@bogon asm]# cat /proc/6129/maps
0046a000-005bd000 r-xp 00000000 08:02639384 /lib/libc-2.5.so
005bd000-005be000 --xp 00153000 08:02639384 /lib/libc-2.5.so
005be000-005c0000 r-xp 00153000 08:02639384 /lib/libc-2.5.so
005c0000-005c1000 rwxp 00155000 08:02639384 /lib/libc-2.5.so
005c1000-005c4000 rwxp 005c1000 00:00 0
008e3000-008e4000 r-xp 008e3000 00:000 [vdso]
00c8b000-00ca6000 r-xp 00000000 08:02639377 /lib/ld-2.5.so
00ca6000-00ca7000 r-xp 0001a000 08:02639377 /lib/ld-2.5.so
00ca7000-00ca8000 rwxp 0001b000 08:02639377 /lib/ld-2.5.so
08048000-08049000 r-xp 00000000 08:02 160831 /cspp/code-all/asm/stack_main
08049000-0804a000 rw-p 00000000 08:02160831 /cspp/code-all/asm/stack_main
b7f87000-b7f89000 rw-p b7f87000 00:00 0
b7f92000-b7f93000 rw-p b7f92000 00:00 0
bffaf000-bffc4000rw-p bffe9000 00:00 0 [stack]
[root@bogon asm]# ./stack_main &
[2] 6309
[root@bogon asm]# local at 0xbf912450
[root@bogon asm]# cat /proc/6309/maps
00110000-00263000 r-xp 00000000 08:02639384 /lib/libc-2.5.so
00263000-00264000 --xp 00153000 08:02639384 /lib/libc-2.5.so
00264000-00266000 r-xp 00153000 08:02639384 /lib/libc-2.5.so
00266000-00267000 rwxp 00155000 08:02639384 /lib/libc-2.5.so
00267000-0026a000 rwxp 00267000 00:00 0
00403000-00404000 r-xp 00403000 00:000 [vdso]
00728000-00743000 r-xp 00000000 08:02639377 /lib/ld-2.5.so
00743000-00744000 r-xp 0001a000 08:02639377 /lib/ld-2.5.so
00744000-00745000 rwxp 0001b000 08:02639377 /lib/ld-2.5.so
08048000-08049000 r-xp 00000000 08:02160831 /cspp/code-all/asm/stack_main
08049000-0804a000 rw-p 00000000 08:02160831 /cspp/code-all/asm/stack_main
b7f73000-b7f75000 rw-p b7f73000 00:00 0
b7f7e000-b7f7f000 rw-p b7f7e000 00:00 0
bf8fe000-bf913000rw-p bffe9000 00:00 0 [stack]
从中可以看到,局部变量的地址确实是在变化的,linux内核有开关可以查看和设置是否打开栈随机化功能。
对于我使用的red hatlinux5.8版本,关闭开关命令如下:
[root@bogon asm]# echo 0>/proc/sys/kernel/randomize_va_space
打开开关的命令:
[root@bogon asm]# echo 1>/proc/sys/kernel/randomize_va_space
关闭开关后:
[root@bogon asm]# ./stack_main &
[3] 6662
[root@bogon asm]# local at 0xbfffe850
[root@bogon asm]# cat /proc/6662/maps
00270000-00271000 r-xp 00270000 00:000 [vdso]
00290000-002ab000 r-xp 00000000 08:02639377 /lib/ld-2.5.so
002ab000-002ac000 r-xp 0001a000 08:02639377 /lib/ld-2.5.so
002ac000-002ad000 rwxp 0001b000 08:02639377 /lib/ld-2.5.so
00a66000-00bb9000 r-xp 00000000 08:02639384 /lib/libc-2.5.so
00bb9000-00bba000 --xp 00153000 08:02639384 /lib/libc-2.5.so
00bba000-00bbc000 r-xp 00153000 08:02639384 /lib/libc-2.5.so
00bbc000-00bbd000 rwxp 00155000 08:02639384 /lib/libc-2.5.so
00bbd000-00bc0000 rwxp 00bbd000 00:00 0
08048000-08049000 r-xp 00000000 08:02160831 /cspp/code-all/asm/stack_main
08049000-0804a000 rw-p 00000000 08:02160831 /cspp/code-all/asm/stack_main
b7ff4000-b7ff6000 rw-p b7ff4000 00:00 0
b7fff000-b8000000 rw-p b7fff000 00:00 0
bffea000-bffff000rw-p bffe9000 00:00 0 [stack]
[root@bogon asm]# ./stack_main &
[4] 6663
[root@bogon asm]# local at 0xbfffe850
[root@bogon asm]# cat /proc/6663/maps
006ca000-006cb000 r-xp 006ca000 00:000 [vdso]
00748000-0089b000 r-xp 00000000 08:02639384 /lib/libc-2.5.so
0089b000-0089c000 --xp 00153000 08:02639384 /lib/libc-2.5.so
0089c000-0089e000 r-xp 00153000 08:02639384 /lib/libc-2.5.so
0089e000-0089f000 rwxp 00155000 08:02639384 /lib/libc-2.5.so
0089f000-008a2000 rwxp 0089f000 00:00 0
00bab000-00bc6000 r-xp 00000000 08:02639377 /lib/ld-2.5.so
00bc6000-00bc7000 r-xp 0001a000 08:02639377 /lib/ld-2.5.so
00bc7000-00bc8000 rwxp 0001b000 08:02639377 /lib/ld-2.5.so
08048000-08049000 r-xp 00000000 08:02160831 /cspp/code-all/asm/stack_main
08049000-0804a000 rw-p 00000000 08:02160831 /cspp/code-all/asm/stack_main
b7ff4000-b7ff6000 rw-p b7ff4000 00:00 0
b7fff000-b8000000 rw-p b7fff000 00:00 0
bffea000-bffff000rw-p bffe9000 00:00 0 [stack]
局部变量在栈上分配的地址不再变化。