LINUX.ORG.RU

История изменений

Исправление vbr, (текущая версия) :

Вариантов много. Самое простое, про которое я знаю - компилятор генерирует код, который при вызове функции сразу после адреса возврата добавляет некое случайное значение (канарейку). А перед возвратом из функции проверяет это значение. Если значение изменилось, значит кто-то проехался по стеку и программа аварийно завершается.

Конечно это несколько замедляет программу.

Если ассемблер можешь читать, просто изучи выхлоп:

https://godbolt.org/

Программа:

// 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, :

Вариантов много. Самое простое, про которое я знаю - компилятор генерирует код, который при вызове функции сразу после адреса возврата добавляет некое случайное значение (канарейку). А перед возвратом из функции проверяет это значение. Если значение изменилось, значит кто-то проехался по стеку и программа аварийно завершается.