我刚刚注意到我的简单程序的数据和堆栈段可执行。 我在/ 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构建的程序使它们的数据,堆栈和堆不可执行,那么为什么用汇编语言编写的行为会以不同的方式运行呢?
答案 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
文件执行此操作。如果任何目标文件需要可执行堆栈或数据,则为整个段设置它。