Global Offset Tables & Procedure Linkage Table
assume you are writing some code and you wanted to use a certain function
well , there is two kinds of functions
- Internal Functions ( defined inside the actual code )
- External Functions ( defined into external libraries )
look at this code below
now all what this program does is calling printf function , which is an external function in libc , now lets compile it and open it in a disassembler , in my case i will open it in Ghidra
navigate to the main function and we will see the call to puts , but wait !!
why is it calling puts ? it should call printf right? well this is because of the compiler optimization and because we specified a constant string , anyway just ignore this for now
lets follow this call now
image src = https://www.youtube.com/watch?v=kUk5pw4w0h4&list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&index=19
now we see that we are not at the puts function in libc , we are in a section called .plt (procedure linkage table) , any binary consist of many sections
.text( code , instructions ) , .data( global data ) .bss ( uninitialized data ) and
the .plt section is just one of them , so what is .plt section and what is its mission? , now we notice that the first instruction here is a jump instruction to an address , this address suppose to be the address of puts in the GOT(global offset table) section , so the .plt section is a link to the .GOT section ,
each function has a specific address in the libc and the program that calls a function does not know by default where is that functions , so this process is necessary
lets follow the code
image src = https://www.youtube.com/watch?v=kUk5pw4w0h4&list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&index=19
what the hell? why didn’t it jump to that address ? does this computer actually work?
well this happened because the GOT section hasn’t updated yet , so we need somehow to update it and go back again to the updated address of puts
observe that there in another jump here that jumps to the address 0x400440
this address is the address to the function dl_runtime_resolve
image src = https://www.youtube.com/watch?v=kUk5pw4w0h4&list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&index=19
and this address of this function belongs to a library called ld.so
now lets read the manual of this library and see what it does
this function would go and look for the address of our function(in this case puts) and updates the .GOT section and when we call puts again the address will be there at the .GOT section so we can execute puts
this is the whole idea of calls to external functions
- going to the .plt section
- jumping to the address specified
- if the .GOT section is not updated go to 4
- ld.so library updates the .GOT section and so we can execute our functions
isn’t this mind plowing !