linux plt 的實(shí)現(xiàn)

Screenshot from 2016-07-25 15-42-57.png

以write函數(shù)為例說(shuō)明延遲綁定,如上圖所示,當(dāng)?shù)谝淮握{(diào)用write函數(shù)時(shí)候,程序會(huì)跳轉(zhuǎn)到.plt表處

Screenshot from 2016-07-25 15-43-31.png

程序首先會(huì)跳轉(zhuǎn)到0x601018處,我們看一下0x601018是什么

Screenshot from 2016-07-25 15-44-32.png

0x601018是一個(gè)地址,這個(gè)地址就是jmp命令的下一條指令的地址。因?yàn)槭堑谝淮蔚谝淮握{(diào)用,此時(shí)got還沒有添加write函數(shù)的實(shí)際地址。當(dāng)重定位完成之后就不會(huì)執(zhí)行0x400586處的指令了。

Screenshot from 2016-07-25 15-46-18.png

我們繼續(xù)調(diào)試,程序會(huì)跳轉(zhuǎn)到0x400570處,這里首先會(huì)將0x601008(*(GOT+8)指向struct link_map的指針)地址的值壓入堆棧,之前的0已經(jīng)在堆棧中了。隨后程序跳轉(zhuǎn)到0x601010處。

Screenshot from 2016-07-25 15-49-01.png

0x601010處存放的是一個(gè)地址即7ffff7dee6a0,這個(gè)地址是dl_runtime_reslove函數(shù)的地址。

Screenshot from 2016-07-25 15-49-16.png

所以重定位最終是調(diào)用dl_runtime_reslove函數(shù)去解析write函數(shù)的實(shí)際地址,解析成功將地址保存到.got.plt表中。以后在調(diào)用write函數(shù)流程就變?yōu)閜lt->got。

dl_runtime_reslove函數(shù)確定符號(hào)的過程如下:


plt.png
_dl_runtime_resolve(link_map, rel_offset);

根據(jù)rel_offset,找到重定位條目:

Elf32_Rel * rel_entry = JMPREL + rel_offset;

根據(jù)rel_entry中的符號(hào)表?xiàng)l目編號(hào),得到對(duì)應(yīng)的符號(hào)信息:

Elf32_Sym *sym_entry = SYMTAB[ELF32_R_SYM(rel_entry->r_info)];

再找到符號(hào)信息中的符號(hào)名稱:

char *sym_name = STRTAB + sym_entry->st_name;

獲取符號(hào)對(duì)應(yīng)的字符串僅僅是一小部分,具體的地址獲取與link_map的實(shí)現(xiàn)息息相關(guān),即壓入堆棧的另一個(gè)參數(shù),這一部分的原理與實(shí)現(xiàn)參考此文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容