動態鏈結的got和plt

2021-07-09 14:04:33 字數 1683 閱讀 6572

更多請搜尋got和plt

其實都大同小異

基本思路:

**中在呼叫共享庫中的函式時(這裡是動態延遲繫結)會call乙個位址(比如0x08048454),而這個位址中儲存的內容是指令

jmp *0x0804a010

0x0804a010是被呼叫函式在got中的位置

如果是第一次呼叫這個函式,則這個位置處的值為0x0804845a

jmp *0x0804a010等價於jmp 0x0804845a

而這個0x0804845a是jmp *0x0804a010的下一條指令的位址(說明第一次呼叫時got項中對應的位址並不是被呼叫函式的實際絕對位址)

0x0804845a處的指令是push $0x20(立即數0x20是被呼叫函式的符號在重定位表.rel.plt中的下標)

再後面的指令就是

jmp 0x08048404(這個位址是plt section的位址,每個未被繫結的函式push完標記後都會跳到plt的開頭)

plt段的**會先pushl 0x8049ff8(0x8049ff8是got[1]的位址,裡面存放的內容是本模組的id)

然後jmp 

*0x8049ffc(0x8049ffc是got[2]的位址,而*

0x8049ffc則為_dl_runtime_resolve函式的位址0x00123270

),所以這條指令是去呼叫了_dl_runtime_resolve函式

_dl_runtime_resolve函式的呼叫如下

0x123270 <_dl_runtime_resolve>

:    push %eax

0x123271 <_dl_runtime_resolve+1>

:    push %ecx

0x123272 <_dl_runtime_resolve+2>

:    push %edx

0x123273 

<

_dl_runtime_resolve+3

>

:mov 0x10(%

esp),%

edx0x123277 <_dl_runtime_resolve+7>

:    mov 0xc(

%esp)

,%eax

0x12327b <_dl_runtime_resolve+11>

:call 0x11d5a0 <_dl_fixup>

0x123280 <_dl_runtime_resolve+16>

:    pop %edx

0x123281 <_dl_runtime_resolve+17>

:    mov (

%esp)

,%ecx

0x123284 <_dl_runtime_resolve+20>

:    mov %eax,

(%esp)

0x123287 <_dl_runtime_resolve+23>

:    mov 0x4(

%esp)

,%eax

可見其呼叫了

_dl_fixup函式(這個函式的作用就是修改0x0804a010處的值為1260912,即被呼叫函式的實際絕對位址

),函式的具體實現還有待研究

然後去呼叫相應的被呼叫函式

上面是第一次,以後再呼叫相同的被呼叫函式時,由於got相應的項中儲存的已經是實際位址,所以就可以直接呼叫了

PLT表和GOT表學習

我們用乙個非常簡單的例子來講解,如下 圖1 然後我們編譯 我們直接 gdb.a.out 來進行反編譯處理,然後通過disas main檢視main函式中的反編譯 如下 圖3 我們可以觀察到 gets plt 和 puts plt 這兩個函式,為什麼後面加了個 plt 因為這個為 plt 表中的資料的...

快速定位ELF的PLT節和GOT節

在修復節表過程中,我們需要準確定位到plt和got這樣,可以快速讓反編譯器快速識別節 以下內容,都測試過android原生的libc linker以及自己編譯的ndk程式,沒有測試obj 在elf的非obj檔案中,plt位於.rel.plt的 檔案 屁股後面,緊挨著,定位.rel.plt的屁股用段表...

PWN基礎15 GOT表 和 PLT表

感謝各位作者的分享精神 事實上,直到第一次呼叫這個函式,都並不知道這個函式的位址,這個功能叫做延遲繫結 lazy bind 因為程式的分支很多,並不是所有的分支都能跑到,比如異常處理,異常處理分支中的動態鏈結庫裡面的函式也許永遠都跑不到 所以,一上來就解析所有出現過的動態庫裡面的函式時個浪費的辦法,...