Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 июня!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Возможности языков семейства Си по истине безграничны, однако, в этой свободе кроются и недостатки: всегда нужно программисту держать ухо востро и контроллировать "переполнение буфера", чтобы потом программа не вылетала в "синий экран" на массе разнообразных версий Windows и железа у пользователей. Те же крэкеры и реверсеры специально ищут в коде программ на Си уязвимости, куда можно подсадить любой вирусный код, об этом более подробно автор рассказывал в своём видеокурсе здесь. Я там многое узнал и теперь мой код стал значительно более безопасный.

Защита от переполнения буфера

Переполнение буфера обычно происходит, когда программа пытается записать данные за пределы конца буфера. Рассмотрим пример:

#include <stdio.h>
 int main()
 {
   char buff[15] = {0};  /*все элементы инициализируются нулём*/
   printf("enter your name: ");
   scanf(buff, "%s"); /*опасно, так как длина не проверяется*/
 }
 

Программа считывает строку со стандартного ввода (клавиатура). Проблема в том, что она не проверяет длину строки. Если будет введено более 14 символов, то произойдёт переполнение буфера, так как scanf() попытается сохранить остальные символы за пределами buff (не забудьте, что один символ всегда зарезервирован для нуля, которым должна заканчиваться строка). В результате обычно происходит аварийное завершение.

Но это ещё не самая страшная ситуация. Намного опаснее, если программа спокойно продолжит своё выполнение. Хотя специалисты, которые знакомы с внутренней организацией системы, могу спокойно встраивать в программный код специальные обработчики таких исключительных ситуаций, которые позволяют проверять правильность следующей интсрукции процессора и решать - продолжать выполнение кода либо пропустить его и вызвать другую подпрограмму, и т.д.

Однако, мы пойдём другим путём. Для начала всегда проверяйте границы массива перед записью его в буфер. Если это невозможно, например, когда ввод производится из скрипта CGI, то используйте функции, которые явно ограничивают количество вводимых сиволов, т.е. вместо scanf() используйте функцию fgets(), которая считывает символы до определённого предела:

#include <stdio.h>
 int main()
 {
  char buff[15] = {0};
  fgets(buff, sizeof(buff), stdin); /*считывает только 14 символов*/
 }
 

Так же стандартные строковые функции имеют аналоги, которые позволяют ограничить размер. Таким образом, вместо strcpy (), strcmp (), и sprintf (), используют strncpy (), strncmp (), и snprint (), соответственно.

 



<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS