【问题标题】:What are the addresses on the left in the output of objdump on a binary file?二进制文件的 objdump 输出中左侧的地址是什么?
【发布时间】:2020-01-01 16:24:02
【问题描述】:

我用gcc -fpie test.c 编译了一个简单的hello world c 代码,现在使用objdump 查看二进制文件:

Disassembly of section __TEXT,__text:
__text:
100000f40:  55                      pushq   %rbp
100000f41:  48 89 e5                movq    %rsp, %rbp
100000f44:  48 83 ec 10             subq    $16, %rsp
100000f48:  89 7d fc                movl    %edi, -4(%rbp)
100000f4b:  8b 75 fc                movl    -4(%rbp), %esi
100000f4e:  48 8d 3d 5d 00 00 00    leaq    93(%rip), %rdi
100000f55:  b0 00                   movb    $0, %al
...

考虑到我用-fpie 编译,这些虚拟(运行时)地址是吗?如果代码与位置无关,它们的用途是什么。

如果我删除fpie,我会在左侧得到相同的地址,并且我假设它们是虚拟地址,这些指令将被加载以纠正?

【问题讨论】:

  • 大多数时候使用-fpie 是没有意义的,因为 GCC 默认会生成 PIE。尝试使用 -fno-pie 编译。
  • 但我想看看为什么我们在饼图模式下仍然有内存地址
  • 另外,您可以使用file 命令判断 EFL 是否与位置无关:对于位置无关的 ELF,它将显示为 ELF Shared Object,对于正常的可执行文件,它将显示为 ELF Executable
  • 在 PIE 模式下你没有内存地址,当你启动程序时这些地址会改变。您看到的是相对地址。
  • 那么代码必须有一个基地址才能开始。那么“位置无关”的分辨率将是一个简单的“向所有地址添加偏移量”。

标签: c shared-libraries objdump


【解决方案1】:

在 PIE(与位置无关的可执行文件)中,这些“地址”实际上只是与程序的基本虚拟地址的相对偏移量。当程序启动时,内核加载器将在0x<base_addr> 处将其加载到内存中,在这种情况下,您的__text 部分将位于0x<base_addr> + 0x100000f40

请注意,如果您启用了 ASLR(地址空间布局随机化)(在任何现代系统上默认启用),则每次执行时基本虚拟地址都会更改。

【讨论】:

  • 但它们仍然是虚拟内存地址,对吧?在运行时,它们会添加一个恒定的偏移量吗?我猜在“no-pie”模式下没有偏移量,它们会在确切的地址位置加载?
  • 嗨@Josh,如果这正确回答了你的问题,请点击左上角的绿色勾号接受它,以便可以将这篇文章标记为已解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
相关资源
最近更新 更多