22

我刚刚注意到我的简单程序具有可执行的数据和堆栈段。我在 /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 构建的程序的数据、堆栈和堆是不可执行的,那么为什么那些用汇编编写的程序的行为方式不同呢?

4

1 回答 1

22

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

如果你将 eg 编译int foo() { return 1; }成程序集(使用gcc -S foo.c),你会看到:

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

对于nasm,语法在手册的第 8.9.2 节中显示;你想要这样的东西:

 section .note.GNU-stack noalloc noexec nowrite progbits

笔记

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

于 2011-10-22T23:09:48.810 回答