3 回答
TA贡献1878条经验 获得超4个赞
int q[200];main(void) { int i; for(i=0;i<2000;i++) { q[i]=i; }}
$ gcc -ggdb3 segfault.c $ ulimit -c unlimited $ ./a.outSegmentation fault (core dumped)
$ gdb -q ./a.out coreProgram terminated with signal 11, Segmentation fault.[New process 7221]#0 0x080483b4 in main () at s.c:88 q[i]=i;(gdb) p i $1 = 1008(gdb)
输入页面。
#include <stdio.h>#include <unistd.h> // sysconf(3)int main(void) { printf("The page size for this system is %ld bytes.\n", sysconf(_SC_PAGESIZE)); return 0;}
此系统的页大小为4096字节。
$ getconf PAGESIZE4096
死后
$gdb -q ./a.out coreCore was generated by `./a.out'.Program terminated with signal 11, Segmentation fault.[New process 4605] #0 0x080483b4 in main () at seg.c:66 q[i]=i;(gdb) p i $1 = 1008(gdb) p &q $2 = (int (*)[200]) 0x804a040(gdb) p &q[199]$3 = (int *) 0x804a35c
TA贡献1799条经验 获得超9个赞
调用函数时堆栈上的数据量,其中包含溢出的变量访问。 总计写入溢出变量/数组的数据量。
SIGSEGV
ret
main()
[ esp ] <return addr to caller> (which exits/terminates process)
[ esp + 4 ] argc
[ esp + 8 ] argv
[ esp + 12 ] envp <third arg to main() on UNIX - environment variables>
[ ... ]
[ ... ] <other things - like actual strings in argv[], envp[]
[ END ] PAGE_SIZE-aligned stack top - unmapped beyond
什么时候main()开始时,它将为各种用途分配堆栈上的空间,其中包括托管待溢出数组。这将使它看起来像:
[ esp ] <current bottom end of stack>
[ ... ] <possibly local vars of main()>
[ esp + X ] arr[0]
[ esp + X + 4 ] arr[1]
[ esp + X + 8 ] arr[2]
[ esp + X + 12 ] <possibly other local vars of main()>
[ ... ] <possibly other things (saved regs)>
[ old esp ] <return addr to caller> (which exits/terminates process)
[ old esp + 4 ] argc
[ old esp + 8 ] argv
[ old esp + 12 ] envp <third arg to main() on UNIX - environment variables>
[ ... ]
[ ... ] <other things - like actual strings in argv[], envp[]
[ END ] PAGE_SIZE-aligned stack top - unmapped beyond
这意味着你可以快乐地进入arr[2].
对于缓冲区溢出导致的不同崩溃的体验,请尝试如下:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int i, arr[3];
for (i = 0; i < atoi(argv[1]); i++)
arr[i] = i;
do {
printf("argv[%d] = %s\n", argc, argv[argc]);
} while (--argc);
return 0;
}
看看异类与堆栈结束后溢出缓冲区时相比,当缓冲区溢出一点(例如,10位)时,就会发生崩溃。用不同的优化级别和不同的编译器来尝试它。很能说明问题,因为它显示了这两种行为的不当行为(不一定会全部打印出来)argv[]以及在不同的地方崩溃,甚至没完没了的循环(例如,编译器放置i或argc到堆栈中,代码在循环期间覆盖它)。
- 3 回答
- 0 关注
- 397 浏览
添加回答
举报