Я згадав про «переповнення буфера» в коментарі до відповіді Пітаграса, я, мабуть, повинен уточнити, що я мав на увазі трохи. У С недостатньо знати, що робота безпосередньо з пам’яттю небезпечна - ви також повинні розуміти точні шляхи небезпеки. Мені не дуже подобається метафора "стріляй собі в ногу" для всіх цих випадків - багато часу, це не ти запускаєш курок, але часто це актор, який має інтереси, що суперечать твоїм та / або вашим користувачам " .
Наприклад, в архітектурі з низхідним стеком (найпопулярніші архітектури відповідають цьому рахунку - x86 і ARM, як правило, включені), коли ви викликаєте функцію, зворотна адреса функції буде розміщена на стеці після локальних змінних, визначених у тіло функції. Отже, якщо ви оголошуєте буфер як локальну змінну і піддаєте цю змінну зовнішньому світу, не перевіряючи переповнення буфера, наприклад:
void myFn(void) {
char buf[256];
gets(buf);
}
зовнішній користувач може надіслати вам рядок, який перезаписує зворотну адресу зі стека - в основному він може змінити уявлення про виконання програми вашої програми про графік викликів, що призводить до поточної функції. Таким чином, користувач надає вам рядок, що є двійковим поданням якогось виконуваного коду для вашої архітектури, достатньо прокладки для переповнення стека myFn
, а також додаткових даних, щоб замінити зворотну адресу, myFn
щоб вказати на код, який він вам дав. Якщо це трапиться, тоді, коли myFn
зазвичай повертається контроль своєму абонентові, він замість цього відгалужується до коду, який надав зловмисний користувач. Якщо ви пишете код C (або C ++), який може піддаватися впливу недовірених користувачів, вам потрібно зрозуміти цей вектор атаки. Ви повинні зрозуміти, чому переповнення буфера до стека часто (але не завжди) легше експлуатувати, ніж один проти купи, і ви повинні розуміти, як пам'ять у купі розкладається (не надто багато деталей, обов'язково, але Ідея про те, що в malloc()
регіоні "ЕД" є контрольні структури, може оточувати її, може допомогти зрозуміти, чому ваша програма виходить з ладу в іншому malloc()
або в free()
).
C піддає вам детальну інформацію про те, як працює ваша машина, і вона надає вам більш безпосередній контроль над вашою машиною, ніж будь-яка інша мова, що редагується користувачем, і широко використовується сьогодні. З великою силою виникає велика відповідальність - вам потрібно зрозуміти ці деталі низького рівня, щоб безпечно та ефективно працювати з C.