elf文件的GOT和PLT
轉自個人博客0pt1mus
0x00 寫在開始
首先,我是從PE文件開始學習的,之后接觸到了Linux下的ELF文件,在本質上來說,無論是Windows下的PE文件,還是Linux下的elf文件,他們本質上都是一個可執行文件,所運行的平臺不同,它們的文件格式也有不同,但究其本質,還是會有互通的地方。
0x01 基礎知識
首先,elf文件也是由眾多的節構成的,可以通過objdump -h查看。
下面解釋.got、.plt、.got.plt三個節。
.got
GOT(Global Offset Table)全局偏移表。這是鏈接器為外部符號填充的實際偏移票。
.plt
PLT(Procedure Linkage Table)程序鏈接表。作用是一個跳板,保存了某個符號在重定位表中的偏移量(用來第一次查找某個符號)和對應的.got.plt的對應的地址。它有兩個功能,要么在.got.plt節中拿到地址,并跳轉。要么當.got.plt沒有所需地址的時候,觸發鏈接器去找到所需的地址。
.got.plt
這個是GOT專門為PLT準備的節。保存了重定位地址。.got.plt中的值是GOT的一部分。它包含上述PLT表所需地址(已經找到的和需要去觸發的)。
實例
比如printf是一個重定位符號,需要鏈接該符號時過程是這樣:
main函數call .plt段中的一個地址,這里的第一句話就是跳轉到.got.plt中的保存的printf的地址,如果是第一次,那么保存的地址就是.plt中的下一句話,這個下一句話就是壓入這個符號在.rel.plt中的重定位表的偏移量,然后ld程序就會根據重定位表中的信息加上這個偏移量找到這個地址,保存到重定位表所指向的地址中,這個地址其實就是.got.plt段的一個地址。
第二次調用時就可以直接獲取到.got.plt中保存的地址了。
0x02 實踐
接下來我們來實踐一下,加深對這幾個節的認識。
首先要有一個分析的程序,我們用一個helloworld。
//gcc -m32 -no-pie -g -o helloworld_li helloworld.c //-g 產生有調試符號的程序 #include<stdio.h> #include<stdlib.h>int main(int argc, char const *argv[]) {puts("Hello World!\n");return 0; }用gdb打開該文件,開始分析:
-
首先反匯編main
-
找到call puts的地址,用b *0x804844b下斷點,r執行到斷點處并通過si單步步入。
我們可以看到當前指令是jmp跳轉指令,跳轉到0x804a00c。
我們之前通過objdump查看該文件的各個節,發現0x804a00c是在.got.plt中。
-
我們使用x/wx 0x804a00c查看這個位置的值。
發現該地址存著的信息是當前執行指令的下一個位置。所以執行jmp [0x804a00c]后會到0x80482e6的位置。
這里就可以理解,在第一次執行時,plt在.got.plt中沒找到puts函數的地址,然后觸發鏈接器去尋找puts函數的地址。
-
通過finish執行完當前函數,然后再查看0x804a00c位置的內容。
可以發現該位置的值已經變了,該地值便是puts函數的地址。
0x03 總結
主要是在學習rop的時候,中間提到了return to libc,通過調用系統函數,而不是shellcode來實現打開shell。有一種方法是return to PLT,因為之前學習的是windows下的,對這個PLT很陌生,因此查資料學習了一下。windows下和linux下,有很多共通的地方,比如說這里的.plt和.got.plt同windows下的PE文件輸入表中的INT和IAT很像。
參考鏈接:https://www.jianshu.com/p/5092d6d5caa3
總結
以上是生活随笔為你收集整理的elf文件的GOT和PLT的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ftp服务器上传文件权限设置,ftp服务
- 下一篇: 当前系统时间与服务器时间,操作系统时间和