состояние стека на момент вызова функции f
Переполняющийся буфер может воздействовать на следующие объекты: а) локальные переменные, расположенные ниже его; б) сохраненный указатель карда стека; в) адрес возврата; г) аргументы, переданные функции; д) на кадр материнской функции. Все эти атаки подробно описаны в статье "ошибки переполнения буфера извне и изнутри как обобщенный опыт реальных атак", поэтому не будем повторяться, а лучше пропустим программу через StackGuard 1.0 и посмотрим, что это даст.
function_prologue:
push 000AFF0Dh ; // забрасываем canary word на стек
; // (следовало это делать после сохранение ebp)
push ebp ; // сохраняем старый указатель карда в стеке
mov ebp, esp ; // открываем новый кадр
sub esp, 98h ; // резервируем место под локальные переменные
; // тело функции
; // (точно такое же, как и в прошлый раз)
function_epilogue:
leave ; // закрываем кадр стека
cmp esp,AFF0Dh ; // проверяем целостность canary word
jne canary_changed ; // если
canary изменено, прыгаем на
canary_changed
add esp,4 ; // удаляем canary из стека
ret ; // возвращаемся в материнскую процедуру
canary_changed: ; // завершаем выполнение программы
call __canary_death_handler
jmp
. ; // если завершить не удалось — зациклившемся