Tôi đang phát với một ví dụ tràn ngăn xếp. Ví dụ này trông giống như sau:Dillema với tràn bộ đệm
void return_input (void){
char array[30];
gets (array);
printf("%s\n", array);
}
main() {
return_input();
return 0;
}
Tất cả mã này có trong tệp gọi là overflow.c. Chúng tôi có chức năng dễ bị tổn thương được gọi là return_input, đặc biệt là mảng char 30 byte. Tôi biên dịch nó và mở chức năng dễ bị tổn thương trong gdb và nhận được sau đầu ra:
(gdb) disas return_input
0x08048464 <+0>: push %ebp
0x08048465 <+1>: mov %esp,%ebp
0x08048467 <+3>: sub $0x48,%esp
0x0804846a <+6>: mov %gs:0x14,%eax
0x08048470 <+12>: mov %eax,-0xc(%ebp)
0x08048473 <+15>: xor %eax,%eax
0x08048475 <+17>: lea -0x2a(%ebp),%eax
0x08048478 <+20>: mov %eax,(%esp)
0x0804847b <+23>: call 0x8048360 <[email protected]>
0x08048480 <+28>: lea -0x2a(%ebp),%eax
0x08048483 <+31>: mov %eax,(%esp)
0x08048486 <+34>: call 0x8048380 <[email protected]>
0x0804848b <+39>: mov -0xc(%ebp),%eax
0x0804848e <+42>: xor %gs:0x14,%eax
0x08048495 <+49>: je 0x804849c <return_input+56>
0x08048497 <+51>: call 0x8048370 <[email protected]>
0x0804849c <+56>: leave
0x0804849d <+57>: ret
End of assembler dump.
Như bạn thấy từ đoạn mở đầu hàm chúng ta reserved hex48 (Tháng Mười Hai 72) byte trên stack cho các biến địa phương. Trước tiên, tôi đã cố gắng tìm địa chỉ nơi mảng dễ bị tấn công của chúng tôi bắt đầu trên ngăn xếp. Tôi nghĩ rằng đó là -0x2a (% ebp), tôi có đúng không? Hex2a là 42 thập phân. Theo tôi hiểu nó có nghĩa là chúng tôi có thể viết một cách an toàn 42 byte trước khi chúng tôi bắt đầu ghi đè lên EBP được lưu trên ngăn xếp. Nhưng khi tôi chạy ví dụ này, chỉ đủ 37 byte để có lỗi phân đoạn:
[email protected]:~/temp/ELF_reader$ ./overflow
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
37 byte đủ để tràn bộ đệm? Nếu mảng char cục bộ của chúng tôi là -42 byte từ lưu EBP
Không liên quan, nhưng [câu hỏi này] (http://stackoverflow.com/questions/9249315/what-is-gs-in-assembly) là * cực kỳ * tương tự. – huon
Trong C, viết 31 byte thành mảng 30 byte là đủ để tràn mảng đó (và nguyên nhân Hành vi không xác định). – pmg