Microsoft Visual Studio .NET
Озабоченная последними хакерскими атаками, Microsoft реализовала в своем новом компиляторе Visual Studio .NET (бывший Visual Studio C++) некоторую разновидность Stack-Guard'а в далеко не лучшей его "инаугурации". Никогда не разрабатывающая собственных продуктов, а только "ворующая" уже готовые (авторитетный товарищ Берзуков в своей софт-панораме об этом только и говорит, сходите на www.softpanorama.org/Bulletin/News/Archive/news078.txt, почитайте— там много интересного), Microsoft, как это часто и бывает, сама не поняла, что стащила и у кого. Ладно, все это лирика. Перейдем к фактам.
При компиляции с ключом /GS компилятор добавляет в код security cookie — так москали кличут пыво, то есть, так в терминологии Microsoft называется случайный 32-битный canary word, хранящийся в writable-памяти и инспектируемый функцией check_canary при выходе из функции:
function _prologue:
push ebp ; // сохраняем прежний указатель кадра
mov ebp, esp ; // открываем новый кадр
sub esp, 9Ch ; // резервируем место для лок. переменных и canary
push edx ; \
push esi ; + - сохраняем регистры которые будут изменены
push edi ; /
mov eax, [canary] ; // копируем глобальный canary в
eax
xor eax, [esp+10h] ; // XOR'им адрес возврата с canary
mov [ebp-10h],eax ; // кладем результат на стек, защищая указатель кадра
; // тело функции
; (не совсем такое же, как и в прошлый раз,
; но различия между компиляторами к делу не относятся)
function_epilogue:
mov ecx, [epb-10h] ; // копируем поXOR'ый canary в ecx
xor ecx, [ebp+10h] ; // XOR'им адрес возврата и кладем его ecx
call check_canary ; // вызываем функцию проверки canary
pop edi ; \
pop esi ; + - восстанавливаем регистры
pop ebx ; /
mov esp, ebp ; // закрываем кадры стека небезопасным путем
pop ebp ; // (Microsoft повторяет ошибку Stack Guard'а)
ret ; // выходим в материнскую функцию
check_canary: ; // функция проверки canary
cmp ecx, [canary] ; // сравниваем переданный ecx с глобальным canary
jnz canary_changed ; // если не совпадают - завершаем программу
ret ; // все ок, продолжаем выполнение программы