Я припускаю, що тут є історія, але чому стек зростає вниз?
Мені здається, що переповнення буфера було б набагато важче експлуатувати, якби стек виріс вгору ...
Я припускаю, що тут є історія, але чому стек зростає вниз?
Мені здається, що переповнення буфера було б набагато важче експлуатувати, якби стек виріс вгору ...
Відповіді:
Я вважаю, що це відбувається з перших днів обчислень, коли пам'ять була дуже обмеженою, і не було розумно заздалегідь виділяти великий шматок пам'яті для виключного використання стеком. Таким чином, розподіляючи пам'ять купи від нульової адреси вгору і стекуючи пам'ять з кінця пам'яті вниз, ви могли б і купу, і стек розділяти одну і ту ж область пам'яті.
Якщо вам знадобилося трохи більше купи, ви можете бути обережними з використанням стеку; якщо вам знадобиться більше стека, ви можете спробувати звільнити деяку купу пам’яті. Результатом, звичайно, були вражаючі збої, оскільки стек час від часу перезаписує купу та навпаки.
Ще в ті часи не було інтервебз, тому не було питання про експлуатацію буфера. (Або принаймні настільки, що існувало інтервебз, все це знаходилось в об'єктах високої безпеки Міністерства оборони Сполучених Штатів, тому про можливість зловмисних даних не потрібно було думати багато.)
Після цього для більшості архітектур було вирішено підтримувати сумісність із попередніми версіями тієї ж архітектури. Тому перевернуті стеки все ще є з нами сьогодні.
пам'ять програми традиційно встановлюється як
code
constants
heap (growing up)
...
stack (growing down)
купу і стек можна обміняти
але переповнення буфера все ще можна експлуатувати, якщо стек пішов іншим шляхом
беручи класичний strcpyза приклад
foo(char* in){
char[100] buff;
strcpy(buff,in);
}
з стеком пам'яті як
ret foo
arg in
buff array
ret strcpy
buf pointer
in
це означало б, що коли копіювання завершено, повернення для адреси strcpyзнаходиться після буфера (замість fooзворотної адреси) і може бути перезаписане тим, що знаходиться вin
Деяке обладнання має купу, починаючи з високої пам'яті, зростаючи, в той час як стек починається з низьким обсягом пам’яті.
Програмне забезпечення HP-PA-RISC, зокрема, робить це: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php
Поважна операційна система Multics працювала на апаратному забезпеченні, яке виростало (один із можливо багатьох) стеків: див. Http://www.acsac.org/2002/papers/classic-multics.pdf , кінець розділу 2.3.2:
По-третє, стеки на процесорах Multics зростали в позитивному, а не в негативному напрямку. Це означало, що якщо ви фактично виконали переповнення буфера, ви замінювали б невикористані кадри стека, а не власний покажчик повернення, що ускладнює експлуатацію значно складніше.
Це досить цікаве твердження. Чи переповнення буфера стали такою величезною проблемою лише через "звичну" процедуру "call-stack-frame"? Крім того, наскільки репутація Multics як "Повністю невразливої" була лише тріском апаратного дизайну?