【问题标题】:Code works when run from section .data, but segmentation faults in section .text代码从 .data 部分运行时有效,但 .text 部分出现分段错误
【发布时间】:2016-11-04 06:36:43
【问题描述】:

为什么下面的代码没有给出分段错误?

global _start
section .data 

_start:
    mov ecx, 3
    xor byte[_start+1], 0x02
    mov eax, 1
    mov ebx, 2
    int 80h

我希望它与在 .text 部分中运行相同的代码时在同一位置(标有注释的行)发生段错误:

global _start
section .text  ; changed from data to text

_start:
    mov ecx, 3
    xor byte[_start+1], 0x02   ; ******get segmentation fault here
    mov eax, 1
    mov ebx, 2
    int 80h           

现在,我知道.data 部分用于读写,而.text 部分用于只读。
但是,当我尝试访问非法内存地址时,这有什么关系呢?

对于此处的示例,我预计在.data 部分也会出现分段错误,与我在.text 部分中得到的位置相同。

【问题讨论】:

  • 嗯,xor指令正在修改_start+1处的字节。在text 部分中,该字节是只读的,而在data 部分中,它是可写的。看来你已经知道了足够的信息来回答你自己的问题,所以我有点困惑。

标签: linux assembly x86 segmentation-fault


【解决方案1】:

[_start+1] 显然不是非法地址。它是 5 字节编码 mov ecx, 3 的一部分。 (查看objdump -Mintel -drw a.out 以查看十六进制机器码的反汇编)。

IDK 为什么您认为写入您已定义内容的.data 中的地址会出现问题。使用db 之类的伪指令将字节组装到数据段中更为常见,但汇编器会很乐意将指令或db 组装到您放置它们的任何位置的字节中。


预期 .data 版本的崩溃是 _start 在未经执行许可的情况下被映射,但由于工具链中令人惊讶的默认设置,带有 asm 源文件的程序通常以read-implies-exec(如gcc -zexecstack),除非您采取预防措施来避免这种情况:

如果您应用了 section .note.GNU-stack noalloc noexec nowrite progbits 更改,从 RIP=_start 获取代码出错。


尝试写入.text 部分的版本当然会出现段错误,因为它被映射为只读。

【讨论】:

  • 好的,所以我明白为什么我在 .data 部分中没有出现 seg-fault。但现在我很困惑——为什么我会在 .text 部分出现段错误?为什么在本节中访问 [_start+1] 的第一个字节会出现问题?
  • @Rodrigo:(修改了之前的评论):您在问题中说您知道.text 被映射为只读。当指令尝试写入映射为只读的页面时会发生什么?
  • 相关:非 shellcode 问题与 .text 中的数组的重复:x86_64 Assembly - Segfault when trying to edit a byte within an array in x64 assembly
猜你喜欢
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
  • 2022-10-07
  • 1970-01-01
  • 2017-02-22
相关资源
最近更新 更多