3 回答

TA貢獻2021條經驗 獲得超8個贊
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貢獻2019條經驗 獲得超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 關注
- 427 瀏覽
添加回答
舉報