Tôi hiện đang đọc (lần thứ hai) "Hacking: The Art of Exploitation" và đã tình cờ gặp điều gì đó.Gcc có sắp xếp lại các biến cục bộ tại thời gian biên dịch không?
Cuốn sách cho thấy hai cách khác nhau để khai thác hai chương trình tương tự: auth_overflow và auth_overflow2
Trong giai đoạn đầu, có một chức năng kiểm tra mật khẩu đặt ra như thế này
int check_authentication(char *password) {
int auth_flag = 0;
char password_buffer[16];
strcpy(password_buffer, password);
...
}
inputing hơn 16 Ký tự ASCII sẽ thay đổi giá trị của auth_flag thành giá trị lớn hơn 0, do đó bỏ qua kiểm tra, như được hiển thị trên đầu ra gdb này:
gdb$ x/12x $esp
0xbffff400: 0xffffffff 0x0000002f 0xb7e0fd24 0x41414141
0xbffff410: 0x41414141 0x41414141 0x41414141 0x00000001
0xbffff420: 0x00000002 0xbffff4f4 0xbffff448 0x08048556
password_buffer @ 0xbffff40c
auth_flag @ 0xbffff41c
Chương trình thứ hai sẽ đảo ngược hai biến:
int check_authentication(char *password) {
char password_buffer[16];
int auth_flag = 0;
strcpy(password_buffer, password);
...
}
Tác giả sau đó gợi ý hơn đó là không thể tràn vào auth_flag, mà tôi thực sự tin tưởng. Tôi sau đó tiến hành tràn bộ đệm, và ngạc nhiên của tôi, nó vẫn hoạt động. Biến auth_flag vẫn ngồi sau bộ đệm, như bạn có thể nhìn thấy trên đầu ra gdb này:
gdb$ x/12x $esp
0xbffff400: 0xffffffff 0x0000002f 0xb7e0fd24 0x41414141
0xbffff410: 0x41414141 0x41414141 0x41414141 0x00000001
0xbffff420: 0x00000002 0xbffff4f4 0xbffff448 0x08048556
password_buffer @ 0xbffff40c
auth_flag @ 0xbffff41c
Tôi tự hỏi nếu gcc không sắp xếp lại các biến cục bộ cho các mục đích Alignement/tối ưu hóa.
Tôi đã cố gắng biên dịch bằng cờ -O0, nhưng kết quả cũng giống nhau.
Có ai trong số các bạn biết tại sao điều này xảy ra không?
Xin cảm ơn trước.
"Sắp xếp lại" bằng cách nào đó ngụ ý rằng bạn mong đợi có một "thứ tự" ban đầu. C++ không thực sự chỉ định bất kỳ loại thứ tự lưu trữ các biến cục bộ nào, bộ nhớ của chúng được gọi là "tự động" - tức là đừng hỏi đừng nói. –
Tôi mong đợi trình biên dịch (với tối ưu hóa của nó bị vô hiệu hoá) để lại thứ tự như được tuyên bố trong mã. Nhưng tôi không biết nhiều về trình biên dịch. Tác giả của cuốn sách dường như cũng mong đợi hành vi tương tự. Tôi vẫn quản lý để làm cho nó hoạt động như tôi muốn bằng cách tuyên bố cả hai biến biến động. – rgehan
Vâng, mong đợi của bạn không may là không tương quan với các quy tắc ngôn ngữ. (Xin lỗi, bạn nói C, không phải C++, nhưng cùng một điểm áp dụng.) "Thực tế khác với mong đợi cá nhân" sẽ là một bản tóm tắt thích hợp về kinh nghiệm của bạn :-) Tự động lưu trữ chỉ là "tự động ở đó", với rất ít chi tiết được bảo đảm. –