Как во время выполнения обнаруживается переполнение буфера? - PullRequest
3 голосов
/ 26 ноября 2010
{
char bufBef[32];
char buf[8];
char bufAfter[32];
sprintf(buf,"AAAAAAA\0");
buf[8]='\0';
printf("%s\n",buf);
}

В Windows 7 я скомпилировал программу с Visual Studio 2008 как отладочный проект.3 буфера соседние.Я нахожу их адреса с помощью отладчика следующим образом:

bufBef           0x001afa50 

buf                  0x001afa40

bufAfter          0x001afa18 

Оператор "buf [8] = '\ 0'" записывает адрес из buf.Когда я запустил программу, операционная система сообщила: «Ошибка отладки: ошибка проверки во время выполнения # 2 - стек вокруг переменной« buf »поврежден».

Затем я скомпилировал его как проект выпуска.Он работает тихо, сообщение об ошибке не возникает.

Мой вопрос: как во время выполнения обнаружить переполнение буфера?

Ответы [ 10 ]

3 голосов
/ 26 ноября 2010

Что вы видите, если эффект от переключателя / RTCs .

Книга Джона Роббинса Отладка приложений для Microsoft .NET и Microsoft Windows подробно об этом говорит.

Соответствующая выдержка:

К счастью для нас, Microsoft расширила ключ / RTCs, чтобы также выполнять проверку переполнения и опустошения всех многобайтовых локальных переменных, таких какмассивы.Это делается путем добавления четырех байтов к началу и концу этих массивов и проверки их в конце функции, чтобы убедиться, что эти дополнительные байты по-прежнему установлены в 0xCC.

Обратите внимание, что этот переключатель работает тольков неоптимизированной сборке (отладочная сборка).

3 голосов
/ 26 ноября 2010

В общем, нет.Вы должны написать защитный код, который выполняет надлежащие проверки, чтобы гарантировать, что он никогда не переполняет буфер.

Среда выполнения отладки добавляет большое количество проверок, чтобы помочь найти этот тип ошибки (и все виды других общихсвязанные ошибки);эти проверки часто очень дороги, поэтому они включаются только в отладочные сборки или при подключении к отладчику.Они также не могут обнаружить каждую возможную ошибку, поэтому они не являются надежными;они просто средства отладки.

2 голосов
/ 26 ноября 2010

Компилятор в режиме отладки выставил дополнительные проверки диапазона для операций.

2 голосов
/ 26 ноября 2010

Три буфера не смежны.Разница между началом buf и началом bufBef (следующий элемент в стеке) составляет 16 байтов, но buf имеет длину всего 8 байтов.предположительно заполненный 8-байтовым «канарейским» значением.Когда среда выполнения обнаруживает, что канарейка была изменена вашей дикой записью, она вызывает ошибку, которую вы видели.и bufBef).

2 голосов
/ 26 ноября 2010

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

2 голосов
/ 26 ноября 2010

Статья в Википедии о Electric Fence объясняет, как перехватывается буфер, и почему вы не должны использовать такие механизмы в рабочем коде.

1 голос
/ 26 ноября 2010

Ну 0x001afa50 - 0x001afa40 = 0x10 = 16 и 0x001afa40 - 0x001afa18 = 0x28 = 40, так что между буферами есть некоторое пространство, чтобы оставить некоторые известные фиктивные данные. Если это изменилось к моменту окончания функции, она знает, что вы вышли за пределы буфера. Я просто размышляю - возможно, они сделали это по-другому, но это кажется одной из возможностей.

1 голос
/ 26 ноября 2010

Вы должны понимать структуру стека. Обычно компилятор размещает дополнительные защитные байты со случайным cookie вокруг массивов, если значение в конце функции не совпадает, возникает переполнение.

0 голосов
/ 26 ноября 2010

Вы ищете язык, отличный от C. Некоторые языки определяют поведение любой возможной программы, определяя специфическое поведение ошибки при выполнении «неправильных» действий. C, с другой стороны, оставляет поведение «неправильного» кода undefined , что означает, что программист должен убедиться, что он / она никогда не использует язык способами, которые приводят к неопределенному поведению. Некоторые реализации ориентированы на отладку или имеют режимы отладки, которые помогают вам находить ошибки, которые вам абсолютно необходимо исправить перед развертыванием кода в выпуске / производственном использовании.

0 голосов
/ 26 ноября 2010

C явно разрешает вам перерасходовать (и недостаточно) свои буферы на свой страх и риск.

Не существует краткого и простого способа обнаружения переполнения буфера во время выполнения (в сборках выпуска).

...