Форум программистов, компьютерный форум CyberForum.ru

Как можно защитить программу от переполнений буфера? - C++

Восстановить пароль Регистрация
 
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
04.10.2010, 00:41     Как можно защитить программу от переполнений буфера? #1
Я тут немного баловался со своей программой,я работаю в Code::Blocks,там свой эмулятор терминала.
Программа принимает параметры
C++
1
int main(int argc, char* argv[])
В качестве последнего параметра ожидается имя файла. Для него резервируется особая переменная filename:
C++
1
2
3
4
5
6
7
8
9
   int main(int argc, char* argv[])
   {
       filename = new char [255];
       ...
       if (cmd_ParamsCheck(filename,argc,argv))
       {
          delete [] filename;
          exit(EXIT_FAILURE);
       }
Функция проверки параметров выглядит так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/* -------------------------------------------------------------------------- */
  int cmd_ParamsCheck(char *const filename,const int argc, const char *const argv[])
  {
      if (argc > static_cast<int>(cmd_options.size() + 2))
      {
         cerr << "\nError: Too much parameters.      \n";
         cmd_PrintMenu();
         return 1;
      }
      if (argc > 2)
      {
         map<string, bool>::const_iterator it;
         map<string, int>temp;
         map<string, int>::const_iterator temp_it;
         for (int i = argc-2; i >= 1; --i)
         {
            it = cmd_options.find(argv[i]);
            temp_it = temp.find(argv[i]);
            if (it == cmd_options.end())
            {
               cerr << "\nError: Unknown parameter.         \n";
               cmd_PrintMenu();
               return 1;
            }
            if (temp_it != temp.end())
            {
               cerr << "\nError: Duplicate parameter.       \n";
               cmd_PrintMenu();
               return 1;
            }
            cmd_options[argv[i]] = true;
            temp[argv[i]];
         }
         strcpy(filename,argv[argc-1]);
         return 0;
      }
      else
      if (argc > 1) {
         strcpy(filename,argv[1]);
         return 0;
      }
      else {
         cmd_PrintMenu();
         return 1;
      }
  }
/* -------------------------------------------------------------------------- */
Я посылаю строку
Код
fdgjs;/media/other/checksec.sh;dfjkgh;lkjghlsdkfjghsldfkghsldkfjjjjjjjjjhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhgdfkjghldkfjghslkdf@jghsdkfjghsld@fkjghsldkfjgha@@sldfkghsldkfghsldfkghsldfkghsldkfjghlsdkfjgh
своей программе и шелл (или просто эмулятор C::B?) выполняет скрипт,имя которого вписано в строку (не вредоносный ,см. прикрепление) ).
Вопрос: Кто-нибудь может пояснить,как именно это работает(я так понял,разделителем служит точка с запятой,но почему вообще строка разделяется?)? Как узнать,где именно происходит переполнение,если оно имеет место,и главное,как от него защититься?
Я физически просто не могу резервировать память под строку неизвестного размера,и как проверить,что ввёл пользователь,а вдруг там строка 2 Гб?
Вывод в эмуляторе терминала C::B:
log
Код
xterm -T Interpreter -e /usr/bin/cb_console_runner /media/src/C++/Projects/CodeBlocks/Interpreter/bin/Debug/Interpreter --noinit-errors fdgjs;/media/other/checksec.sh;dfjkgh;lkjghlsdkfjghsldfkghsldkfjjjjjjjjjhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhgdfkjghldkfjghslkdf@jghsdkfjghsld@fkjghsldkfjgha@@sldfkghsldkfghsldfkghsldfkghsldkfjghlsdkfjgh
usage: checksec OPTIONS
    --file <binary name>
    --dir <directory name>
    --proc <process name>
    --proc-all
    --proc-libs <process ID>
    --kernel
    --version
sh: dfjkgh: not found
sh: lkjghlsdkfjghsldfkghsldkfjjjjjjjjjhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhgdfkjghldkfjghslkdf@jghsdkfjghsld@fkjghsldkfjgha@@sldfkghsldkfghsldfkghsldfkghsldkfjghlsdkfjgh: Filename too long

Или я неправильно понял смысл происходящего и это просто так работает эмулятор в Code::Blocks?
Но про посылку параметров всё же интересно,как это делается.
Вложения
Тип файла: zip checksec.sh.zip (4.4 Кб, 11 просмотров)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
04.10.2010, 00:52     Как можно защитить программу от переполнений буфера? #2
Мб

fdgjs;/media/other/checksec.sh;dfjkgh;

; - токен?

П.С. от переполнения как мне кажется лучше всего спасает std::string...

А так же. strncpy - впринципе должен... Вообщем что-то, что ограничивает кол-во вводимых символов. А дальше пиши сколько хочешь, больше чем нужно прочитано не будет.
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
04.10.2010, 00:54  [ТС]     Как можно защитить программу от переполнений буфера? #3
К сожалению,второй параметр программы,который она принимает от операционной системы,должен быть char**
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
04.10.2010, 00:59     Как можно защитить программу от переполнений буфера? #4
#pragma, Ну да.. Но что мешает привести в std::string?

C++
1
std::string S=argv[1];
ЗЫ, если нельзя тогда strncpy или написать свою функцию, которая копирует не более n символов и завершает строку нулевым символом...
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2293 / 1663 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
04.10.2010, 01:02     Как можно защитить программу от переполнений буфера? #5
#pragma, действенный способ избежать переполнения буфера - это использование функций, одним из параметров которых передается размер буфера, как, например, указанный Lavroff'ым strncpy. Тем более такие вещи, как максимальная длина пути файла, известны, по крайней мере в Windows (MAX_PATH). В Линуксе, думаю, тоже должно быть какое-то ограничение.
Yandex
Объявления
04.10.2010, 01:02     Как можно защитить программу от переполнений буфера?
Ответ Создать тему
Опции темы

Текущее время: 09:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru