2012-06-17 32 views
6

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

+0

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

+0

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

Trả lời

6

Thật khó để nói mà không nhìn thấy toàn bộ việc tháo gỡ chức năng.

Tuy nhiên, tôi đoán là% gs: 0x14 được lưu trữ ở -0xc (% ebp) có thể là stack canary của bạn gây ra một lối thoát sạch nếu phát hiện ra một chồng coruption. Vì vậy, giá trị này được lưu trữ ở -0xc (% ebp), có nghĩa là bộ đệm của bạn thực tế chỉ có 30 byte lớn, tiếp theo là bất kỳ giá trị nào xuất hiện sau đó.

+0

Cảm ơn dude, biên dịch lại không có bảo vệ ngăn xếp gcc, và mã lắp ráp cung cấp tất cả các giá trị chính xác. –

Các vấn đề liên quan