程序集部分 .code 和 .text 的行为不同
Assembly section .code and .text behave differently
我是汇编新手,据我了解,.code
与 .text
相同,但使用 .code
.
下面的代码会崩溃
segment .data
msg db "hello, world", 0xa
len equ $ - msg
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
nasm -f elf64 -o hello.o hello.s
ld -s -o hello hello.o
hello, world
sed -i s/.text/.code/ ./hello.s
nasm -f elf64 -o hello.o hello.s
ld -s -o hello hello.o
./stack.sh: line 8: 4621 Segmentation fault (core dumped) ./hello
其实我觉得没什么不同。为什么会这样?
在 Linux 使用标准工具链 (GNU Binutils ld
) 时,.text
是一个“特殊”部分名称,得到特殊处理(默认为 exec 权限),但是 .code
不是。 (其他特殊部分包括 .data
(可写)和 .bss
(可写 nobits),并且都具有默认对齐方式 > 1。)
section .text
是 NASM ELF/Linux 等价于 Windows MASM .code
指令,但 不是 表示 Linux 工具识别 .code
指令或节名 1.
section .code
和section xyz123
没有区别;它只使用默认值 noexec
nowrite
. 请参阅 the table in the NASM docs.
底部的 other
条目
使用 readelf -a hello
查看节(链接)和段(程序加载器)属性,明显缺少任何地方的 X
。
脚注 1:事实上,我认为 Windows 可执行文件仍然使用实际的节名称 .text
。至少 GNU objdump -d
仍然说代码在 .text
部分。
所以 MASM .code
指令是切换到 .text
部分的快捷方式。
有趣的事实:如果您将其构建为 32 位代码(您应该 ), like in 在错误移植时使用 section .code
从 16 位 MASM 代码到 Linux NASM.
或者,如果您 运行 旧内核上的 64 位代码。
原因是在没有明确指定 PT_GNU_STACK
注释的情况下,内核对 32 位可执行文件使用向后兼容假设并使用影响每个页面的 READ_IMPLIES_EXEC
: .即使对于 64 位可执行文件,较旧的内核也会这样做,在这种情况下,较新的内核只会使堆栈本身可执行。
将 section .note.GNU-stack noalloc noexec nowrite progbits
添加到您的源代码会使其出现段错误,即使构建到 32 位可执行文件中也是如此。 (nasm -felf32
/ ld -melf_i386 -o foo foo.o
)。参见 this answer。
另见旧情况。
我是汇编新手,据我了解,.code
与 .text
相同,但使用 .code
.
segment .data
msg db "hello, world", 0xa
len equ $ - msg
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
nasm -f elf64 -o hello.o hello.s
ld -s -o hello hello.o
hello, world
sed -i s/.text/.code/ ./hello.s
nasm -f elf64 -o hello.o hello.s
ld -s -o hello hello.o
./stack.sh: line 8: 4621 Segmentation fault (core dumped) ./hello
其实我觉得没什么不同。为什么会这样?
在 Linux 使用标准工具链 (GNU Binutils ld
) 时,.text
是一个“特殊”部分名称,得到特殊处理(默认为 exec 权限),但是 .code
不是。 (其他特殊部分包括 .data
(可写)和 .bss
(可写 nobits),并且都具有默认对齐方式 > 1。)
section .text
是 NASM ELF/Linux 等价于 Windows MASM .code
指令,但 不是 表示 Linux 工具识别 .code
指令或节名 1.
section .code
和section xyz123
没有区别;它只使用默认值 noexec
nowrite
. 请参阅 the table in the NASM docs.
other
条目
使用 readelf -a hello
查看节(链接)和段(程序加载器)属性,明显缺少任何地方的 X
。
脚注 1:事实上,我认为 Windows 可执行文件仍然使用实际的节名称 .text
。至少 GNU objdump -d
仍然说代码在 .text
部分。
所以 MASM .code
指令是切换到 .text
部分的快捷方式。
有趣的事实:如果您将其构建为 32 位代码(您应该 section .code
从 16 位 MASM 代码到 Linux NASM.
或者,如果您 运行 旧内核上的 64 位代码。
原因是在没有明确指定 PT_GNU_STACK
注释的情况下,内核对 32 位可执行文件使用向后兼容假设并使用影响每个页面的 READ_IMPLIES_EXEC
:
将 section .note.GNU-stack noalloc noexec nowrite progbits
添加到您的源代码会使其出现段错误,即使构建到 32 位可执行文件中也是如此。 (nasm -felf32
/ ld -melf_i386 -o foo foo.o
)。参见 this answer。
另见