为什么数据和堆栈段是可执行的?

时间:2011-10-22 23:04:08

标签: linux assembly nasm memory-mapping

我刚刚注意到我的简单程序的数据和堆栈段可执行。 我在/ 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

导致prog执行int3指令。

用C语言编写并用gcc构建的程序使它们的数据,堆栈和堆不可执行,那么为什么用汇编语言编写的行为会以不同的方式运行呢?

1 个答案:

答案 0 :(得分:18)

在现代Linux系统上,链接器将标记堆栈/数据不可执行 IFF 参与该链接的所有对象都有一个特殊的“标记”部分.note.GNU-stack

如果你编译,例如int foo() { return 1; }加入程序集(gcc -S foo.c),您会看到:

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

对于nasm,语法显示在section 7.9.2 of the manual;你想要这样的东西:

 section .note.GNU-stack noalloc noexec nowrite progbits

注意

必须为进入可执行文件的每个 .o文件执行此操作。如果任何目标文件需要可执行堆栈或数据,则为整个段设置它。