Добрый день! Есть некоторая программа на С, в котором допустим такой код: Код (Text): char szBuffer[20]; void main(){ // здесь переполняем глобальный буфер szBuffer strcpy(szBuffer,"12345678901234567890123"); } Есть ли способ, с помощью которого можно обнаружить такого рода переполнения? Пробовал использовать отладочную CRT но там я так понял отлавливаются только утечки , возникшие с использованием malloc/free и прочих. Какая вообще стратегия для отлова таких вот переполнений? В инете нарыл только по переполнениям стека, выделенной нами кучи .
ну или вот такой код: Код (Text): void main(){ // здесь переполняем глобальный буфер szBuffer char szBuffer[20]; strcpy(szBuffer,"12345678901234567890123"); getch();// вот тут хотелось бы чтобы в Outputе показало, что произошло переполнение! } Стек слетит конечно по окончании работы main, тем не менее, кажется что должны быть средства, чтобы еще до окончании ф-ии main, но после самого strcpy можно бы было определить, что произошло переполнение.
Это классическое переполнение буфера в стеке. Оно призвано затереть точку возврата из функции и в случае неумышленного переполненя крашнуть программу, а в случае умышленого передать управление на зловредный код. Отсюда вытекает ответ. Надо контролировать целостность точки возврата. Если интересует переполнение именно в главной функции то не очень помню, а если из внутренней функции то можно посмотреть на реализацио от майкрософт (в студии 2005 этот тип защиты включен по умолчанию ) Где то кажется была статья Русиновича по этому поводу а вообще есть в немного в MSDN. _http://msdn.microsoft.com/en-us/security/aa570425.aspx тут чуть чуть
paymera - Иключение вызвать - потребуется замена селектора, тоесть придётся использовать LDT, что некоторые значительные проблемы вносит. - Проверять память после исполнения уязвимой процедуры(ставить метки в памяти до исполнения и проверять после, например заполнением области какимито значениями), собственно частным случаем в виндовс является програмная DEP.
Ты не там ищешь ответ. Переформулирую вопрос: "На заборе написано - Не входить, злая собака! Я вошел, что мне делать?" Теперь ответ очевиден? PS: 'int main'
Написать пост побудила именно такого рода ошибка(моя) сделанная в коде весьма большого проекта. По стеку вызовов определить где именно зашита проблема не представлялось возможным. После вычитки кода нашел место - просто буфер был мал для строки. Но это потребовало внимательного рассмотрения каждой ф-ии, анализа последовательности вызовов и тд. Посему и возник вопрос , как такое дело вылавливается НА УРОВНЕ возможностей VC6 ну или выше, потому что в отладчике уже после краха что-либо нарыть просто нереально - просто потому, что проект - дллка, внедряемая в скажем другое приложение, которое подгружает кучу других дллок, работает с сетью и тд. И такая незамеченная тихо подпорченная буферная область вызвала пессимизм по поводу вообще возможности в студии как-нибудь автоматизировать отлов таких досадных багов. Вот как например есть отладочная версии c runtime - все выделения и освобождения отслеживаются и в нужный момент поднимается стата - сколько байт утекло , что-то типа такого хочется. Судя по всему не так то просто все...
paymera Баги случаются (с) Форест Гамп Посмотри багтракет и убедишся в этом. На своих ошибках надо учится и если уж пишешь на С то запомнить святое правила програмирования, всегда и везде проверять и контролировать всеми возможными свособами длину строки записываемый в буфер. ВСЕГДА! И ВЕЗДЕ! Даже если кажется что тут ну вот нкак не может быть переполнеия. Длоя автоматического поиска подобного рода уязвимостей существует остаточно много программ как платных и так и фриварных, работающих как с исходными кодами так и с готовой программой подкладывая ей неправильные данные. Если безопасноть в конторе пунктик и ценится превыше всего не жалейте время на использование таких программ. Так же есть достаточно много как называемых SDL(security development lifecycle) и не стоит пренебрегать -Wall опцией компилятора.
Может это прозвычит банально - об этом надо заботиться раньше. Для любых данных поступающих извне должна существовать политика проверки на валидность. Определение 'извне' может варьироваться в зависимости от степени доверия к источнику данных. Конкретно для приведенного кода: >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'" Но здесь компилятору явно известна строка и ее размер. Никто и не общеал что будет просто... Отладочная версия не спасет, если нет заранее приготовленного набора данных на котором происходит порча памяти. А если такой набор есть, то следовательно определены требования к поступающим извне данным. Остается только выразить эти требования в коде.
Понял, благодарю за ответы. Думал есть что-либо простое и очевидное, о котором я просто никогда не знал и не задумывался о наличии оного! Придется писать внимательно