在具有标准工具链的 Linux 上(GNU Binutilsld
), .text
是一个得到特殊处理的“特殊”节名称(默认情况下具有执行权限),但是.code
不是。 (其他特殊部分包括.data
(可写)和.bss
(可写 nobits),并且所有默认对齐方式 > 1。)
section .text
is the NASM ELF/Linux equivalent of Windows MASM .code
directive, but that does not mean that Linux tools recognize a .code
directive or section name1.
section .code
与section xyz123
;它只是使用默认值noexec
nowrite
.请参阅other
底部的条目NASM 文档中的表格 https://www.nasm.us/xdoc/2.11.08/html/nasmdoc7.html#section-7.9.2.
Use readelf -a hello
查看节(链接)和段(程序加载器)属性,明显缺少X
任何地方。
脚注1:事实上,我认为Windows可执行文件仍然使用实际的节名称.text
。至少是 GNUobjdump -d
仍然说代码在.text
部分。
所以面膜.code
指令是切换到的快捷方式.text
部分。
有趣的事实:如果您将其构建为 32 位代码(您应该因为它只使用 32 位int 0x80系统调用 https://stackoverflow.com/questions/46087730/what-happens-if-you-use-the-32-bit-int-0x80-linux-abi-in-64-bit-code), 像这个案例 https://stackoverflow.com/questions/57316059/assembly-code-do-not-recognise-and-data使用过的section .code
当错误地从 16 位 MASM 代码移植到 Linux NASM 时。
或者,如果您在较旧的内核上运行 64 位代码。
原因是没有明确指定PT_GNU_STACK
请注意,内核对 32 位可执行文件使用向后兼容假设并使用READ_IMPLIES_EXEC
这会影响每个页面:Linux 可执行文件 .data 部分的默认行为在 5.4 和 5.9 之间发生了变化? https://stackoverflow.com/questions/64833715/linux-default-behavior-of-executable-data-section-changed-between-5-4-and-5-9。较旧的内核甚至对于 64 位可执行文件也会这样做,在这种情况下,较新的内核仅使堆栈本身可执行。
Adding section .note.GNU-stack noalloc noexec nowrite progbits
即使构建到 32 位可执行文件中,您的源代码也会出现应有的段错误。 (nasm -felf32
/ ld -melf_i386 -o foo foo.o
). See 这个答案 https://stackoverflow.com/questions/7863200/why-data-and-stack-segments-are-executable.
也可以看看当程序集文件包含在项目中时,来自 mmap 的意外执行权限 https://stackoverflow.com/questions/58260465/unexpected-exec-permission-from-mmap-when-assembly-files-included-in-the-project关于旧的情况。