【问题标题】:Nasm - Symbol `printf' causes overflow in R_X86_64_PC32 relocation [duplicate]Nasm - 符号“printf”导致 R_X86_64_PC32 重定位溢出[重复]
【发布时间】:2018-06-12 18:25:36
【问题描述】:

我正在尝试在 nasm 中创建一个应该显示字母 a 的简单程序。但是,它给了我一个 Segfault 并说:

./a.out: Symbol `printf' causes overflow in R_X86_64_PC32 relocation
Segmentation fault (core dumped)

基本上,我试图将值 0x61(字母 a 的十六进制)移动到内存地址 1234,然后将其作为参数传递给 printf。这是我的确切代码:

extern printf
section .text
global main
main:
push rbp
mov rax,0
mov qword [1234], 0x61 ; move 0x61 into address 1234
mov rdi, qword [1234] ; mov address 1234 into rdi
call printf ; should print the letter a
pop rbp
mov rax,0
ret

我正在运行 Linux x86_64

【问题讨论】:

  • 内存地址 1234 在 Linux 上几乎可以肯定是不可写的。 Printf 将格式字符串作为第一个参数。在这段代码中看不到任何这样的格式字符串。
  • 在与位置无关的 64 位代码中对 printf 的调用应该类似于 call [printf wrt ..got]
  • printf 可以不带格式字符串调用
  • 总是有一个格式字符串。如果您只是打印一个字符串,则格式是实际的字符串。如果要打印单个字符,可以使用格式说明符"%c",第二个参数是要打印的字符。或者你想创建一个包含单个字符的 NUL 终止字符串?
  • 这样的事情可能会起作用:default rel ; Use RIP relative addressing by default.main: xor eax, eaxpush 0x61 ; Push 0x61 onto stack followed by 7 bytes of 0x00lea rdi, [rsp] ; Address of character a on stackcall [printf wrt ..got]add rsp, 8 ; restore stackxor eax,eax ; return 0ret

标签: linux gcc segmentation-fault nasm x86-64


【解决方案1】:

尝试使用-no-pie 编译,查看这些帖子以获得解释: Assembling with GCC causes weird relocation error with regards to .data

简而言之:

Debian 在您的情况下切换到 64 位模式和 GCC 的 PIC/PIE 二进制文件 正在尝试将您的对象链接为 PIC,但它会遇到绝对 地址在 mov $str, %rdi.

【讨论】:

  • 不仅仅是 64 位模式。甚至 gcc -m32 默认情况下也会使 PIE 可执行,这很讨厌,因为这会将 ebx 与 GOT 指针联系在一起。 (在 32 位模式下没有 RIP 相对寻址。)顺便说一句,这不会使 OP 的程序工作,因为它试图从 [1234] 存储/重新加载,这肯定会出现段错误!
  • 相关:32-bit absolute addresses no longer allowed in x86-64 Linux? 也解释了默认的-pie 东西。
【解决方案2】:

完全归功于 https://stackoverflow.com/users/3062591/brian

为了弄清楚如何让它发挥作用。如果您像我一样对 nasm 非常陌生,或者由于某种原因您是 nasm 新手并且对 gcc 几乎没有做任何事情,那么您将需要运行以下命令:

nasm -felf64 YOUR_FILE.asm && gcc -no-pie YOUR_FILE.o && ./a.out

我可以使用

调用 printf

不需要改成

printf wrt ..got

之前尝试过一些 NASM 介绍性示例,但不是全部。

【讨论】:

猜你喜欢
  • 2014-05-06
  • 2016-06-30
  • 2019-01-02
  • 2011-10-31
  • 2019-12-12
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
  • 2012-07-29
相关资源
最近更新 更多