@plt 在这里是什么意思?

2024-10-14 08:40:00
admin
原创
107
摘要:问题描述:0x00000000004004b6 <main+30>: callq 0x400398 <printf@plt> 有人知道吗?更新为什么两个disas printf给我不同的结果?(gdb) disas printf Dump of assembler...

问题描述:

0x00000000004004b6 <main+30>:   callq  0x400398 <printf@plt>

有人知道吗?

更新

为什么两个disas printf给我不同的结果?

(gdb) disas printf
Dump of assembler code for function printf@plt:
0x0000000000400398 <printf@plt+0>:  jmpq   *0x2004c2(%rip)        # 0x600860 <_GLOBAL_OFFSET_TABLE_+24>
0x000000000040039e <printf@plt+6>:  pushq  $0x0
0x00000000004003a3 <printf@plt+11>: jmpq   0x400388

(gdb) disas printf
Dump of assembler code for function printf:
0x00000037aa44d360 <printf+0>:  sub    $0xd8,%rsp
0x00000037aa44d367 <printf+7>:  mov    %rdx,0x30(%rsp)
0x00000037aa44d36c <printf+12>: movzbl %al,%edx
0x00000037aa44d36f <printf+15>: mov    %rsi,0x28(%rsp)
0x00000037aa44d374 <printf+20>: lea    0x0(,%rdx,4),%rax
0x00000037aa44d37c <printf+28>: lea    0x3f(%rip),%rdx        # 0x37aa44d3c2 <printf+98>

解决方案 1:

这是一种获取代码修复(根据代码在虚拟内存中的位置调整地址,而不同进程的地址可能不同)的方法,无需为每个进程维护单独的代码副本。PLT(即过程链接表)是使动态加载和链接更易于使用的结构之一(另一个是 GOT(即全局偏移表))。

请参阅下图,其中显示了调用代码和库代码(您调用的)映射到两个不同进程中的不同虚拟地址:AB。实际内存中每段代码只有一个副本,每个进程内的不同虚拟地址映射到该实际地址:

Process A
    Addresses (virtual):
        0x1234                      0x8888
        +-------------+ +---------+ +---------+
        |             | | Private | |         |
        |             | | PLT/GOT | |         |
        | Shared      | +---------+ | Shared  |
    ===== application =============== library =====
        | code        | +---------+ | code    |
        |             | | Private | |         |
        |             | | PLT/GOT | |         |
        +-------------+ +---------+ +---------+
        0x2020                      0x6666
Process B

当共享库被引入到地址空间时,将在进程特定的(私有的)PLT 和/或 GOT 中构建条目,这些条目将在首次使用时执行一些修复以使运行速度更快。后续使用将绕过修复,因为不再需要它。

整个过程大致如下。

printf@plt实际上是一个小存根,它(最终)调用真正的printf函数,并在调用过程中进行修改,以加快后续调用速度。

真实 函数printf被映射到给定进程(虚拟地址空间)中的任意位置,就像试图调用它的代码一样。

因此,为了允许调用代码(左侧上方)和被调用代码(右侧)的正确代码共享,您不能直接对调用代码应用任何修复,因为这会“损害”它在其他进程中的工作方式(如果它映射到每个进程中的相同位置,那就无关紧要了,但这是一个有点限制,特别是如果其他东西已经映射到那里)。

因此,在可靠计算的运行时地址处PLT有一个较小的特定于进程的区域,该区域不会在进程之间共享,因此任何给定的进程都可以自由地更改它,而不会对其他进程产生不利影响。


让我们更详细地了解一下这个过程。上图没有显示 PLT/GOT 的地址,因为可以使用相对于当前程序计数器的位置来找到它。这可以通过您的 PC 相对查找来证明:

<printf@plt+0>: jmpq  *0x2004c2(%rip)  ; 0x600860 <_GOT_+24>

通过在被调用库中使用位置无关代码以及 PLT/GOT,对函数的第一次printf@plt调用(在 PLT 中)是一个多阶段操作,其中执行以下操作:

  • 它调用 GOT 版本(通过指针),该版本最初指向 PLT 中的某些设置代码。

  • 如果尚未完成,该设置代码将加载相关的共享库,然后修改GOT 指针,以便后续调用直接转到实际printf(在特定于进程的虚拟地址)而不是 PLT 设置代码。

  • 然后它调用printf该地址处加载的代码。

后续调用中,由于 GOT 指针已被修改,因此多阶段方法得到简化:

  • 它调用 GOT 版本(通过指针),现在指向真实 printf

这里有一篇很好的文章,详细介绍了如何glibc在运行时加载。

解决方案 2:

不确定,但您看到的内容可能有意义。第一次运行 disas 命令时,printf 尚未被调用,因此尚未解析。一旦您的程序第一次调用 printf 方法,GOT 就会更新,现在 printf 已解析,GOT 指向真实函数。因此,下一次调用 disas 命令会显示真实的 printf 汇编。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用