0

Whenever there is a call to a function of a dynamically linked library (0x400586 in the example at the end), the call first leads to a few lines in the .plt section, which in turn starts with a jmp to an address found in the GOT (see 0x400450). It looks like this (unconditional!) jmp does not get executed the first time, which makes sense, as the GOT has not been set up yet, and will be done with the following lines (0x400456). But what kind of magic prevents the jmp at 0x400450 from being taken the first time?

here's some code to clarify my question:

0x400586: call 0x400450 <puts@plt>

puts@plt then looks like this:

0x400450: jmp QWORD PTR [rip+0x200bc2]
0x400456: push 0x0
0x40045b: jmp 0x400440
2

In the file on disk, the GOT slot referenced in 0x400450 is initially set up with the address of the PLT stub at 0x400456.

So, the jump is taken the first time and goes to 0x400456 which pushes the target symbol's index (0 here) and jumps to the resolver (PLT0) stub at 0x400440 which finally goes to the dynamic loader routine, which:

  1. looks up the target symbol's address using the symbol index
  2. patches the GOT slot so it points to the target (puts)
  3. jumps to the target so that the program behaves as if it was called directly.

So, the next time puts@plt is called, the jump goes directly to the already-resolved puts without going through the dynamic loader again.

I recommend you to follow these steps in a debugger for a clearer picture.

  • perfect - thanks for the detailed explanation! – bayer Dec 3 '16 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.