Нотификация о переполнении глобального буфера

Тема в разделе "LANGS.C", создана пользователем paymera, 18 июн 2009.

  1. paymera

    paymera New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2009
    Сообщения:
    15
    Добрый день!
    Есть некоторая программа на С, в котором допустим такой код:
    Код (Text):
    1.     char szBuffer[20];
    2.     void main(){
    3.         // здесь переполняем глобальный буфер szBuffer
    4.         strcpy(szBuffer,"12345678901234567890123");
    5.     }
    Есть ли способ, с помощью которого можно обнаружить такого рода переполнения? Пробовал использовать отладочную CRT но там я так понял отлавливаются только утечки , возникшие с использованием malloc/free и прочих. Какая вообще стратегия для отлова таких вот переполнений? В инете нарыл только по переполнениям стека, выделенной нами кучи .
     
  2. paymera

    paymera New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2009
    Сообщения:
    15
    ну или вот такой код:
    Код (Text):
    1.     void main(){
    2.         // здесь переполняем глобальный буфер szBuffer
    3.         char szBuffer[20];
    4.         strcpy(szBuffer,"12345678901234567890123");
    5.         getch();// вот тут хотелось бы чтобы в Outputе показало, что произошло переполнение!
    6.     }
    Стек слетит конечно по окончании работы main, тем не менее, кажется что должны быть средства, чтобы еще до окончании ф-ии main, но после самого strcpy можно бы было определить, что произошло переполнение.
     
  3. friackazoid

    friackazoid New Member

    Публикаций:
    0
    Регистрация:
    4 июн 2009
    Сообщения:
    102
    Это классическое переполнение буфера в стеке. Оно призвано затереть точку возврата из функции и в случае неумышленного переполненя крашнуть программу, а в случае умышленого передать управление на зловредный код.
    Отсюда вытекает ответ. Надо контролировать целостность точки возврата. Если интересует переполнение именно в главной функции то не очень помню, а если из внутренней функции то можно посмотреть на реализацио от майкрософт (в студии 2005 этот тип защиты включен по умолчанию )
    Где то кажется была статья Русиновича по этому поводу а вообще есть в немного в MSDN.
    _http://msdn.microsoft.com/en-us/security/aa570425.aspx тут чуть чуть
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    paymera
    - Иключение вызвать - потребуется замена селектора, тоесть придётся использовать LDT, что некоторые значительные проблемы вносит.
    - Проверять память после исполнения уязвимой процедуры(ставить метки в памяти до исполнения и проверять после, например заполнением области какимито значениями), собственно частным случаем в виндовс является програмная DEP.
     
  5. friackazoid

    friackazoid New Member

    Публикаций:
    0
    Регистрация:
    4 июн 2009
    Сообщения:
    102
    Для такого есть функция strncpy
     
  6. nop_

    nop_ New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2007
    Сообщения:
    61
    Ты не там ищешь ответ. Переформулирую вопрос: "На заборе написано - Не входить, злая собака! Я вошел, что мне делать?" Теперь ответ очевиден?

    PS: 'int main'
     
  7. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Сделать собаку доброй?
     
  8. paymera

    paymera New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2009
    Сообщения:
    15
    Написать пост побудила именно такого рода ошибка(моя) сделанная в коде весьма большого проекта. По стеку вызовов определить где именно зашита проблема не представлялось возможным. После вычитки кода нашел место - просто буфер был мал для строки. Но это потребовало внимательного рассмотрения каждой ф-ии, анализа последовательности вызовов и тд. Посему и возник вопрос , как такое дело вылавливается НА УРОВНЕ возможностей VC6 ну или выше, потому что в отладчике уже после краха что-либо нарыть просто нереально - просто потому, что проект - дллка, внедряемая в скажем другое приложение, которое подгружает кучу других дллок, работает с сетью и тд. И такая незамеченная тихо подпорченная буферная область вызвала пессимизм по поводу вообще возможности в студии как-нибудь автоматизировать отлов таких досадных багов. Вот как например есть отладочная версии c runtime - все выделения и освобождения отслеживаются и в нужный момент поднимается стата - сколько байт утекло , что-то типа такого хочется. Судя по всему не так то просто все...
     
  9. friackazoid

    friackazoid New Member

    Публикаций:
    0
    Регистрация:
    4 июн 2009
    Сообщения:
    102
    paymera
    Баги случаются (с) Форест Гамп
    Посмотри багтракет и убедишся в этом. На своих ошибках надо учится и если уж пишешь на С то запомнить святое правила програмирования, всегда и везде проверять и контролировать всеми возможными свособами длину строки записываемый в буфер. ВСЕГДА! И ВЕЗДЕ! Даже если кажется что тут ну вот нкак не может быть переполнеия.
    Длоя автоматического поиска подобного рода уязвимостей существует остаточно много программ как платных и так и фриварных, работающих как с исходными кодами так и с готовой программой подкладывая ей неправильные данные. Если безопасноть в конторе пунктик и ценится превыше всего не жалейте время на использование таких программ.
    Так же есть достаточно много как называемых SDL(security development lifecycle) и не стоит пренебрегать -Wall опцией компилятора.
     
  10. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Думаю компилятор с версией выше чем VC6 просто не даст скомпилировать программу с strcpy.
     
  11. nop_

    nop_ New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2007
    Сообщения:
    61
    Может это прозвычит банально - об этом надо заботиться раньше. Для любых данных поступающих извне должна существовать политика проверки на валидность. Определение 'извне' может варьироваться в зависимости от степени доверия к источнику данных.

    Конкретно для приведенного кода:

    >cl c:\temp\test.cpp /analyze /W4
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
    Copyright (C) Microsoft Corporation. All rights reserved.

    "c:\temp\test.cpp(10) : warning C6202: Buffer overrun for 'szBuffer', which is possibly stack allocated, in call to 'strcpy': length '24' exceeds buffer size '20'"

    Но здесь компилятору явно известна строка и ее размер.

    Никто и не общеал что будет просто... Отладочная версия не спасет, если нет заранее приготовленного набора данных на котором происходит порча памяти. А если такой набор есть, то следовательно определены требования к поступающим извне данным. Остается только выразить эти требования в коде.
     
  12. nop_

    nop_ New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2007
    Сообщения:
    61
    Делаем сами себе проблемы и сами же решаем их?
     
  13. paymera

    paymera New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2009
    Сообщения:
    15
    Понял, благодарю за ответы. Думал есть что-либо простое и очевидное, о котором я просто никогда не знал и не задумывался о наличии оного! Придется писать внимательно:)
     
  14. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Простое и очевидное это использовать современный компилятор, а не 10ти летней давности.
     
  15. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Используй C++ и std::tr1::array<> + реализуй safe_copy через at() и будет out_of_range().