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