【问题标题】:Absolute Jumps Within Shared Object Code Unix共享对象代码 Unix 中的绝对跳转
【发布时间】:2023-03-09 13:52:01
【问题描述】:

我有一个关于共享库的处理和解释的问题。

假设,我使用以下命令从 foo.c 构建一个共享对象:

gcc -shared -fPIC -o libfoo.so foo.c

其中 foo.c 包含:

#include <stdlib.h>
#include <stdio.h>

int main(void) {

  int i;
  printf("this is a silly test\n");

  if(i)
    goto ret;

  printf("hello world\n");

 ret:
 return 0;
}

现在,让我们看看 objdump 的输出,特别是 foo 的 main 输出:

0000000005ec <main>: 
 5ec:   55                      push   %rbp
 5ed:   48 89 e5                mov    %rsp,%rbp
 5f0:   48 83 ec 10             sub    $0x10,%rsp
 5f4:   48 8d 3d 6b 00 00 00    lea    0x6b(%rip),%rdi        # 666 <_fini+0xe>
 5fb:   e8 00 ff ff ff          callq  500 <puts@plt>
 600:   83 7d fc 00             cmpl   $0x0,-0x4(%rbp)
 604:   75 0e                   jne    614 <main+0x28>
 606:   48 8d 3d 65 00 00 00    lea    0x65(%rip),%rdi        # 672 <_fini+0x1a>
 60d:   e8 ee fe ff ff          callq  500 <puts@plt>
 612:   eb 01                   jmp    615 <main+0x29>
 614:   90                      nop
 615:   b8 00 00 00 00          mov    $0x0,%eax
 61a:   c9                      leaveq 
 61b:   c3                      retq   
 61c:   90                      nop
 61d:   90                      nop
 61e:   90                      nop
 61f:   90                      nop

我可以清楚地看到,对 put 的调用正按预期重定向到 PLT。但是,我不明白的是604和612的指令。它们与IP无关,也不是对PLT的调用。他们使用绝对地址,基于 符号主要。

这个共享库怎么可能在多个进程之间同时使用呢?它可以(并且应该)加载到不同的虚拟地址,但关键是每个进程应该共享存储在 RAM 中的实现。 main 加载在不同虚拟地址的不同进程如何共享 604 和 612 处的指令?

【问题讨论】:

  • X86 操作码 75(十六进制)和 eb 是相对跳转,而不是绝对跳转,您的清单中的操作数说明了这一点。反汇编可能会因为给出实际的目标地址而使您感到困惑;而是查看机器代码。

标签: c unix linker dynamic-linking


【解决方案1】:

它们不是绝对跳跃,而是 PC 相对跳跃。事实上,所有直接跳转和调用指令在 x86 上都是 PC 相关的——没有绝对直接跳转(所以如果你想要绝对跳转,它必须是间接的)。

callq 指令使用 PLT 的原因是因为目标符号可能在一个不同的共享对象中,所以即使是相对分支也不起作用(其他共享对象可能在任何地址,独立于这个共享对象)。 PLT 本身实际上是共享对象中的一小段代码,每个远程符号都有一个(间接)绝对跳转。当共享对象动态加载时,绝对地址设置得当,所以当代码运行时,callq 指令将是一个到 PLT 的 pc 相对分支(调用),其中包括到 puts 例程的单个间接跳转。

【讨论】:

    猜你喜欢
    • 2021-12-18
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多