为什么ELF64可执行文件中的.dynsym项未初始化



我有一个x86-64可执行文件,我正在尝试使用静态方法对其进行分析。从_start开始,我看到跳转到0x400648——PLT中的一个地址——它包含指令jmp *0x20065a(%rip)。这个跳跃导致*0x600ca8,实际上是0x40064e。这使我们回到PLT并执行pushq $0x2

这就是我的困境:我知道pushq $0x2指令的存在是为了告诉动态链接器解析.dynsym表中的第三个条目。问题是该条目中的st_value字段是0x0。这个值实际上应该是main相对于_start的偏移量,对吧?如果是,如何初始化st_value字段?

这个值实际上应该是main从_start的偏移量,对吧?

错了。您不能只是从_start跳到main——后者需要argcargv[]参数,但还没有人设置它们。libc初始化代码的任务是:

  • 初始化libc本身,创建标准的FILE句柄(stdout等),设置环境等
  • 使用正确的参数调用main,以及
  • 如果/当main返回时,用正确的退出代码将程序安排到exit(2)

您看到的实际上是PLT__libc_start_main的调用,它将执行上述所有操作,然后调用main。你可以在objdump -dr a.out中看到这一点,它看起来类似于:

00000000004003d0 <_start>:
  4003d0:       31 ed                   xor    %ebp,%ebp
  4003d2:       49 89 d1                mov    %rdx,%r9
  4003d5:       5e                      pop    %rsi
  4003d6:       48 89 e2                mov    %rsp,%rdx
  4003d9:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  4003dd:       50                      push   %rax
  4003de:       54                      push   %rsp
  4003df:       49 c7 c0 50 05 40 00    mov    $0x400550,%r8
  4003e6:       48 c7 c1 c0 04 40 00    mov    $0x4004c0,%rcx
  4003ed:       48 c7 c7 b4 04 40 00    mov    $0x4004b4,%rdi
  4003f4:       e8 c7 ff ff ff          callq  4003c0 <__libc_start_main@plt>
  4003f9:       f4                      hlt
  4003fa:       90                      nop
  4003fb:       90                      nop

stvalue字段是如何初始化的?

您可以在这里阅读动态符号解析如何工作的实际细节(搜索"过程链接表";请注意:很少有人真正了解它是如何详细工作的)。

最新更新