История изменений
Исправление vbr, (текущая версия) :
Вариантов много. Самое простое, про которое я знаю - компилятор генерирует код, который при вызове функции сразу после адреса возврата добавляет некое случайное значение (канарейку). А перед возвратом из функции проверяет это значение. Если значение изменилось, значит кто-то проехался по стеку и программа аварийно завершается.
Конечно это несколько замедляет программу.
Если ассемблер можешь читать, просто изучи выхлоп:
Программа:
// Type your code here, or load an example.
int square(int num) {
int x[num];
return num * num;
}
Опция -fstack-protector
square(int):
push rbp
mov rbp, rsp
sub rsp, 48
mov DWORD PTR [rbp-36], edi
mov rax, QWORD PTR fs:40
mov QWORD PTR [rbp-8], rax
xor eax, eax
mov rax, rsp
mov rcx, rax
mov eax, DWORD PTR [rbp-36]
movsx rdx, eax
sub rdx, 1
mov QWORD PTR [rbp-24], rdx
cdqe
lea rdx, [0+rax*4]
mov eax, 16
sub rax, 1
add rax, rdx
mov esi, 16
mov edx, 0
div rsi
imul rax, rax, 16
sub rsp, rax
mov rax, rsp
add rax, 3
shr rax, 2
sal rax, 2
mov QWORD PTR [rbp-16], rax
mov eax, DWORD PTR [rbp-36]
imul eax, eax
mov rsp, rcx
mov rdx, QWORD PTR [rbp-8]
sub rdx, QWORD PTR fs:40
je .L3
call __stack_chk_fail
.L3:
leave
ret
Вот это fs:40 это и есть канарейка.
Исправление vbr, :
Вариантов много. Самое простое, про которое я знаю - компилятор генерирует код, который при вызове функции сразу после адреса возврата добавляет некое случайное значение (канарейку). А перед возвратом из функции проверяет это значение. Если значение изменилось, значит кто-то проехался по стеку и программа аварийно завершается.
Конечно это несколько замедляет программу.
Исходная версия vbr, :
Вариантов много. Самое простое, про которое я знаю - компилятор генерирует код, который при вызове функции сразу после адреса возврата добавляет некое случайное значение (канарейку). А перед возвратом из функции проверяет это значение. Если значение изменилось, значит кто-то проехался по стеку и программа аварийно завершается.