这是什么意思@plt这里? [英] What does @plt mean here?

查看:1171
本文介绍了这是什么意思@plt这里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  0x00000000004004b6<主+ 30计算值:callq 0x400398< printf的PLT @>

任何人都知道?

更新

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

 (GDB)disas的printf
汇编code的printf函数@ PLT的转储:
0x0000000000400398< printf的PLT @ 0 +计算值:jmpq * 0x2004c2(%RIP)#0x600860< _GLOBAL_OFFSET_TABLE_ + 24 GT;
0x000000000040039e< printf的PLT @ + 6计算值:pushq $为0x0
0x00000000004003a3< printf的PLT @ + 11计算值:jmpq 0x400388(GDB)disas的printf
汇编code的printf函数的转储:
0x00000037aa44d360<的printf + 0计算值:子$ 0xd8,RSP%
0x00000037aa44d367< printf的+ 7计算值:MOV%的RDX,的0x30(%RSP)
0x00000037aa44d36c&所述; printf的+ 12计算值:movzbl%人,%EDX
0x00000037aa44d36f< printf的+ 15计算值:MOV%RSI,0x28(%RSP)
0x00000037aa44d374&所述; printf的+ 20计算值:LEA为0x0(,%RDX,4),%RAX
0x00000037aa44d37c< printf的+ 28计算值:LEA 0x3F的(%RIP),RDX%#&0x37aa44d3c2 LT; printf的+ 98>


解决方案

在这里 >(搜索 PLT ),这是一种方式来获得code的修正,而无需保持code的单独副本为每个进程。该PLT是过程链接表,这使得动态加载更易于使用的建筑之一。

的printf @ PLT 实际上是调用了真正的的printf 函数的小存根。这种实时功能可以映射到的任何的在给定的虚拟地址空间中的位置,这样,为了让自己的code正确code共享(左侧下方),你不吨要对地址的调整直接适用于它,因为它也可以在任何地方的虚拟地址空间映射。

PLT 变种是较小的特定过程面积不的共享,以便给定的过程中可以改变但就是了。

在换句话说:

 映射到:为0x12345678 0x90000000 0x88888888
        + ------------------------- + + ---------- + ---------- + ----------- +
        | | |民营| | |
PROCA | | | PLT / GOT | | |
        | | |区| | |
        | | + ---------- + | |
======== |共享应用程序code | ============== |共享库code | ========
        | | + ---------- + | |
        | | |民营| | |
ProcB | | | PLT / GOT | | |
        | | |区| | |
        + ------------------------- + + ---------- + ---------- + ----------- +
         映射到:0x20202020 0x90000000 0x66666666

这是在这里对​​PLT映射到已知位置的简单情况。在您的情况,似乎因此它可能是以下共享的应用程序code一个单独的部分将位于相对于当前程序计数器。你可以看到,在您的加入,在拆卸:

 < printf的PLT @ 0 +计算值:jmpq * 0x2004c2(%RIP)#0x600860< _GLOBAL_OFFSET_TABLE_ + 24 GT;

这显然使用程序计数器相对查找,找到的实际的printf 功能。这 _GLOBAL_OFFSET_TABLE _ 根据需要将举行修复起坐尽可能多的功能。

另一个好文章可以在这里找到 ,详细的glibc如何在运行时加载。

基本上,其中文库取得的原始的方式意味着它们必须在所使用他们每进程的虚拟地址空间中的相同的存储单元被装载。如果不是这样,他们不能被共享,因为固定了的法案的的共享一个进程将完全东西了它被映射到不同的位置,另一个进程副本。

通过使用与位置无关code,具有全局偏移表(GOT)和PLT以来,第一次调用的printf @ PLT (在PLT)是一个多级运行,其中:

在后续调用,因为GOT已被修改:

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

Anyone knows?

UPDATE

Why two disas printf give me different result?

(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>

解决方案

From here (search for plt), it's a way to get code fixups without having to maintain a separate copy of the code for each process. The PLT is the procedure linkage table, one of the structures which makes dynamic loading easier to use.

printf@plt is actually a small stub which calls the real printf function. This real function may be mapped into any location in a given virtual address space so, in order to allow proper code sharing of your own code (left side below), you don't want to apply the fixups to it directly since it too can be mapped anywhere in the virtual address space.

The plt variant is a smaller process-specific area which isn't shared so a given process can change that however it wants to.

In other words:

         Mapped to: 0x12345678       0x90000000   0x88888888
        +-------------------------+ +----------+ +---------------------+
        |                         | | Private  | |                     |
ProcA   |                         | |  PLT/GOT | |                     |
        |                         | |   area   | |                     |
        |                         | +----------+ |                     |
========| Shared application code |==============| Shared library code |========
        |                         | +----------+ |                     |
        |                         | | Private  | |                     |
ProcB   |                         | |  PLT/GOT | |                     |
        |                         | |   area   | |                     |
        +-------------------------+ +----------+ +---------------------+
         Mapped to: 0x20202020       0x90000000   0x66666666

This is a simple case where the PLT maps to a known location. In your scenario, it appears to be located relative to the current program counter so it's probably a separate section following the shared application code. You can see that in your added-in disassembly:

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

It's clearly using a program-counter-relative lookup to find the actual printf function. That _GLOBAL_OFFSET_TABLE_ will hold fix-ups for as many functions as needed.

Another good article can be found here, detailing how glibc is loaded at runtime.

Basically, the original way in which libraries were made meant that they had to be loaded at the same memory location in the virtual address space of every process that used them. Either that or they couldn't be shared, since the act of fixing up the single shared copy for one process would totally stuff up another process where it was mapped to a different location.

By using position independent code, along with a global offset table (GOT) and the PLT, the first call to printf@plt (in the PLT) is a multi-stage operation, in which:

  • you call printf@plt in the PLT.
  • it calls the GOT version which initially points back to some set-up code in the PLT.
  • that set-up code modifies the GOT so that subsequent calls don't use the setup code (instead they go directly to the real printf).

On subsequent calls, because the GOT has been modified:

  • you call printf@plt in the PLT.
  • it calls the GOT version which points to the real printf.

这篇关于这是什么意思@plt这里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆