【问题标题】:Locating the Global Offset Table in an ELF file在 ELF 文件中定位全局偏移表
【发布时间】:2017-02-26 09:18:08
【问题描述】:

如何在我正在解析的 ELF 文件中找到 .got 部分的偏移量?

我不想按名称搜索该部分,因为我不想依赖它。当我用其他东西更改部分名称时,二进制文件仍然有效。

【问题讨论】:

  • 通过使用elf.h的code()还是通过命令行??
  • 不是命令行;也不是在运行时。我想解析 ELF 文件以找出 .got 部分的偏移量;不依赖于部分名称(可能不可靠)
  • 你为什么要这么做?
  • 在某些系统上,这会给出反汇编的 GOT:objdump -d -j .got path/to/yourlib.so

标签: c++ linux elf


【解决方案1】:

简短回答:一般情况下,您不能。

链接视图中的 GOT

流程的链接视图由节头表给出。 GOT 可以通过以下方式定位:

$ readelf -S $elf [...] 部分标题: [Nr] 名称类型地址偏移量 大小 EntSize 标志链接信息对齐 [29] .got 程序 00000000003a2d80 001a2d80 0000000000000278 0000000000000008 西澳 0 0 8 [30] .got.plt 程序 00000000003a3000 001a3000 0000000000000078 0000000000000008 西澳 0 0 8

您只能识别 GOT,因为部分名称(实际上可以是任何名称)。 GOT 条目使用 SHT_PROGBITS(与 ELF 文件的许多其他位一样),因此您无法使用节类型来识别它们。

此外,节头表在运行时不需要,也不需要出现在 ELF 文件中。

执行视图

我们可以改用执行视图吗?

执行视图由程序头表给出。但是,在程序头表中,没有真正的(非PLT)GOT概念。运行时不关心 GOT 条目的位置。它们也可以散布在数据段中的任何位置*。重要的是(运行时)重定位表中存在正确的重定位。

使用动态部分

需要告诉动态链接器 PLT GOT 条目在哪里 (.got.plt)。这是由动态部分的DT_PLTGOT 条目给出的。但是,它只给出了 GOT PLT 表开始的(运行时,虚拟内存)位置:你没有它的大小。

使用重定位表

您可以尝试检查重定位表:

  • 您应该能够通过查看 PLT 重定位来推断 PLT GOT 的大小;

  • 您或许可以通过查看非 PLT 重定位来推断非 PLT GOT 的位置和大小。

如果我查看 libc 的非 PLT 重定位表(在 x86_64 上),我会得到一堆 R_X86_64_GLOB_DAT 条目:

$ readelf -r $elf [...] 0000003a2da0 052c00000006 R_X86_64_GLOB_DAT 00000000003a4708 标准错误 + 0 0000003a2da8 061400000006 R_X86_64_GLOB_DAT 00000000003a85d0 error_one_per_line + 0 0000003a2db0 06eb00000006 R_X86_64_GLOB_DAT 00000000003a57d0 __malloc_initialize_ho + 0 0000003a2db8 07f300000006 R_X86_64_GLOB_DAT 00000000003a4720 __morecore + 0 0000003a2dc8 02a400000006 R_X86_64_GLOB_DAT 00000000003a8998 __key_encryptsession_p + 0 0000003a2dd0 061000000006 R_X86_64_GLOB_DAT 00000000003a3ec8 __progname_full + 0 0000003a2dd8 049c00000006 R_X86_64_GLOB_DAT 00000000003a4010 __ctype32_tolower + 0 0000003a2de0 011900000006 R_X86_64_GLOB_DAT 00000000003a5fb8 _environ + 0 0000003a2de8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 _rtld_global + 0 0000003a2df0 011000000006 R_X86_64_GLOB_DAT 00000000003a3ec0 __progname + 0 0000003a2df8 04ff00000006 R_X86_64_GLOB_DAT 00000000003a32c4 argp_err_exit_status + 0 0000003a2e08 04ce00000006 R_X86_64_GLOB_DAT 00000000003a8538 mallwatch + 0 0000003a2e10 00bc00000006 R_X86_64_GLOB_DAT 00000000003a87d8 __rcmd_errstr + 0 0000003a2e18 056400000006 R_X86_64_GLOB_DAT 00000000003a48e0 __vdso_clock_gettime + 0 [...]

我们几乎找到了非PLT GOT的地址:

$ readelf -S $elf [...] [29] .got 程序 00000000003a2d80 001a2d80 0000000000000278 0000000000000008 西澳 0 0 8

缺少 4 个 GOT 条目(我不知道为什么……)。

注意

(*):这意味着甚至可能没有任何(非 PLT)GOT。

【讨论】:

  • 遗憾的是,您只是粘贴了输出,而不是相关的命令
  • @Holmes.Sherlock:每个sn -p的第一行是命令。
猜你喜欢
  • 1970-01-01
  • 2013-06-14
  • 1970-01-01
  • 2021-07-08
  • 2017-05-03
  • 1970-01-01
  • 2019-12-31
  • 2015-02-11
  • 2011-01-12
相关资源
最近更新 更多