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

时间:2013-07-19 14:11:20

标签: assembly x86 gdb executable reverse-engineering

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

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

1 个答案:

答案 0 :(得分:1)

  

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

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

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

您所看到的实际上是对PLT __libc_start_main的{​​{1}}来电,它将执行上述所有操作,然后调用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
  

如何初始化st_value字段?

您可以阅读有关动态符号解析如何工作的实际细节here(搜索“程序链接表”;请注意:很少有人真正了解其工作原理)。