动态库代码存根的执行流程

时间:2014-05-17 12:40:48

标签: linux dll shared-libraries glibc

StackOverflow上几乎没有关于类似标题的问题,但这个问题解决了不同的问题。

我创建了一个简单的fprintf程序,它在文件中打印一定的值。我想了解程序相对于库代码的执行流程。我对动态库的分析是使用存根在目标文件的plt部分中的存根来调用每个动态库。对象文件的简单objdump显示了三个主要部分:init,plt和text。 plt部分中的所有存根由3/4个相似的线组成。 fprintf示例:

00000000004004d0 <fprintf@plt>:
  4004d0: jmpq   *0x200b42(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x30>
  4004d6: pushq  $0x3
  4004db: jmpq   400490 <_init+0x18>

我使用pintool来跟踪程序的执行情况。显然,第一次调用fprintf时,执行流程为4004d0,4004d6,4004db。这意味着第一条指令,即跳转到第一次的下一条指令,然后下一次,相同的跳转指令导致库代码(我可以从下一条指令的ip中识别出来)。

  1. 我的查询是在目标文件中维护的 _GLOBAL_OFFSET_TABLE _ 信息在哪里?我使用 readelf -a 命令来读取目标文件内容,但在该目标文件中找不到感兴趣的指令指针。
  2. plt部分和stub方法是我们访问共享库代码的唯一方法吗?

1 个答案:

答案 0 :(得分:1)

  

我使用pintool来跟踪程序的执行情况。显然,第一次调用fprintf时,执行流程为4004d0,4004d6,4004db。这意味着第一条指令,即跳转到第一次的下一条指令,然后下一次,相同的跳转指令导致库代码(我可以从下一条指令的ip中识别出来)。

恭喜,您已经观察到了懒惰的符号重定位。阅读更多相关信息here(特别是“懒惰的绑定优化”部分)。

  

我的查询是目标文件中维护的_GLOBAL_OFFSET_TABLE_信息在哪里?

它不是(正如阅读引用的博客文章所示)。