как уже отмечалось, перехват каждого переполнения буфера затруднен. В моем предыдущем проекте у компилятора не было опций, подобных указанным manneorama. К счастью, вся база кода никогда не вызывала malloc напрямую, правила кода (строго соблюдаемые) при каждом вызове malloc должны вызывать функцию, которая по умолчанию использовалась для вызова malloc (давайте назовем ее mymalloc).
Итак, мы создали дополнительный размер буфера, скажем, 4 дополнительных байта (2 до и 2 после запрошенной памяти. Заполните их байтами, которые, как вы ожидаете, не будет записан в коде (и именно здесь решение не является правильным) )
В верхнем заголовочном файле определите макрос:
#define mymalloc(X) testmalloc(X,__FILE__,__LINE__)
и определите функцию testmalloc следующим образом:
void * testmalloc(size_t size, char *filename, int linenum)
{
void *buff = malloc(size + 4)
char *bytebuff = (char *) buff
//bookkeeping, keep record of buff
bytebuff[0] = 0xBA;
bytebuff[1] = 0xBA;
bytebuff[size+2] = 0xBA;
bytebuff[size+3] = 0xBA;
return bytebuff[2];
}
(этот код у меня в памяти, реальный код у меня нет, поэтому возможны незначительные ошибки)
И всякий раз, когда вам нужно проверить на переполнение, просто напишите процедуру, которая проходит через все такие буферы и проверяет байты. Макросы предварительной обработки __FILE__
и __LINE__
должны отслеживать, какая строка программы вызывает переполнение.
Это не гарантирует, что все переполнения будут восприняты как:
- программа может переполниться тем же байтом (здесь 0xBA)
- программа может сохранять защитные байты без изменений, но выходит за пределы диапазона
Это была легкая задача для нас, поскольку очень дисциплинированная кодовая база сделала этот код за несколько минут усилий, и мы обнаружили несколько интересных ошибок.
Также этот механизм ограничен массивами, выделенными для кучи.