Почему данные и сегменты стека являются исполняемыми? - PullRequest
16 голосов
/ 23 октября 2011

Я только что заметил, что моя простая программа имеет исполняемые сегменты данных и сегментов стека. Я видел это в / proc / [pid] / maps, и простой код подтвердил это.

Например:

; prog.asm
section .data
    code:   db 0xCC    ;int3

section .text
global _start
_start:
    jmp    code

    mov    rax, 60    ; sys_exit
    mov    rdi, 0
    syscall

тогда

nasm -f elf64 prog.asm
ld -o prog prog.o
./prog

заставляет прогу выполнить инструкцию int3.

Программы, написанные на C и построенные с помощью gcc, имеют свои данные, стек и кучу неисполняемыми, так почему программы, написанные на ассемблере, ведут себя по-разному?

1 Ответ

18 голосов
/ 23 октября 2011

В современных системах Linux компоновщик помечает стек / данные как неисполняемые IFF Все объекты, участвующие в ссылке, имеют специальный раздел «маркер» .note.GNU-stack.

Если вы компилируете, например, int foo() { return 1; } в сборку (с gcc -S foo.c), вы увидите это:

    .section    .note.GNU-stack,"",@progbits

Для nasm синтаксис показан в разделе 7.9.2 руководства ; Вы хотите что-то вроде этого:

 section .note.GNU-stack noalloc noexec nowrite progbits

Примечание

Это должно быть сделано для каждого .o файла, который входит в исполняемый файл. Если для какого-либо объектного файла требуется исполняемый стек или данные, он устанавливается для всего сегмента.

...