汇编节.code和.text的行为不同 [英] Assembly section .code and .text behave differently

查看:118
本文介绍了汇编节.code和.text的行为不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是汇编语言的新手,从中学到的 .code .text 相同,但是下面的代码将使用 .code崩溃.

I'm new to assembly and from what I learned the .code is same with .text, but the code below will crash using the .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

实际上,我认为没有什么不同.为什么会这样?

Actually, I don't think it's different. Why this happen ?

推荐答案

在带有标准工具链(GNU Binutils ld )的Linux上, .text 是特殊"的;节名称得到特殊处理(默认情况下具有执行权限),但 .code 不是.(其他特殊部分包括 .data (可写)和 .bss (可写点),且所有默认对齐方式均为> 1.)

On Linux with the standard toolchain (GNU Binutils ld), .text is a "special" section name that gets special treatment (exec permission by default), but .code isn't. (Other special sections include .data (writeable) and .bss (writable nobits), and all with a default alignment > 1.)

section .text 是Windows MASM .code 指令的NASM ELF/Linux等效项,但这 not 并不意味着Linux工具可以识别 .code 指令或节名称 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.

部分.code 部分xyz123 相同;它只使用默认值 noexec nowrite .请参见other 条目://www.nasm.us/xdoc/2.11.08/html/nasmdoc7.html#section-7.9.2"rel =" nofollow noreferrer> NASM文档中的表格.

section .code is no different from section xyz123; it just uses the defaults which are noexec nowrite. See the other entry at the bottom of the table in the NASM docs.

使用 readelf -a hello 查看section(链接)和segment(程序加载器)属性,而在任何地方都明显缺少 X .

Use readelf -a hello to see the section (linking) and segment (program-loader) attributes, with a distinct lack of an X anywhere.

脚注1:实际上,我认为Windows可执行文件仍使用实际的节名称 .text .至少GNU objdump -d 仍然说代码在 .text 部分中.因此,MASM .code 指令是切换到 .text 部分的快捷方式.

Footnote 1: In fact, I think Windows executables still use the actual section name .text. At least GNU objdump -d still says the code is in the .text section. So the MASM .code directive is a shortcut for switching to the .text section.

有趣的事实:这确实是偶然"正确运行的.如果您将其构建为32位代码(您应该这种情况在错误地从16位MASM代码移植到Linux时使用了 section .code NASM.
或者,如果您要在较旧的内核上运行64位代码.

Fun fact: this does happen to run correctly "by accident" if you build it as 32-bit code (which you should because it's using only 32-bit int 0x80 system calls), like in this case that used section .code when incorrectly porting from 16-bit MASM code to Linux NASM.
Or if you'd run your 64-bit code on an older kernel.

原因是,在没有显式指定 PT_GNU_STACK 注释的情况下,内核对32位可执行文件使用了向后兼容的假设,并使用了影响每个页面的 READ_IMPLIES_EXEC : Linux可执行文件的默认行为.data部分在5.4和5.9之间更改?.即使是64位可执行文件,较旧的内核也会执行此操作,在这种情况下,较新的内核只会使堆栈本身可执行.

The reason is that without explicitly specifying a PT_GNU_STACK note, the kernel uses backwards-compat assumptions for 32-bit executables and uses READ_IMPLIES_EXEC which affects every single page: Linux default behavior of executable .data section changed between 5.4 and 5.9?. Older kernels do this even for 64-bit executables, newer kernels only make the stack itself executable in this case.

在源代码中添加 section .note.GNU-stack noalloc noexec noexec progbits 可以使它像段错误那样出现,即使内置到32位可执行文件中也是如此.( nasm -felf32 / ld -melf_i386 -o foo foo.o ).参见此答案.

Adding section .note.GNU-stack noalloc noexec nowrite progbits to your source makes it segfault as it should, even when build into a 32-bit executable. (nasm -felf32 / ld -melf_i386 -o foo foo.o). See this answer.

另请参见>意外的exec权限从mmap中获取有关旧情况的项​​目中的程序集文件时.

这篇关于汇编节.code和.text的行为不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆