PLT Hook基本原理

最近經(jīng)常用到PLT hook,接下來幾篇文章,給大家介紹一下PLT hook的原理、使用、案例、以及一些注意事項(xiàng)。

今天是第一篇,先來介紹一下PLT Hook的基本原理。

ELF文件格式

ELF:Executable and Linkable Format

動(dòng)態(tài)鏈接庫就是ELF格式的文件,要搞清楚PLT Hook的原理,首先要了解ELF文件格式。

image.png

ELF分為連接視圖和執(zhí)行視圖。

  • 連接視圖:ELF未被加載到內(nèi)存執(zhí)行前,以section為單位的數(shù)據(jù)組織形式
  • 執(zhí)行視圖:ELF被加載到內(nèi)存后,以segment為單位的數(shù)據(jù)組織形式

PLT Hook是運(yùn)行中修改內(nèi)存中的數(shù)據(jù),所以我們主要關(guān)心的是執(zhí)行視圖。

linker依據(jù)ELF文件執(zhí)行視圖中的信息,用mmap將ELF加載到內(nèi)存中,執(zhí)行relocation將外部引用的絕對(duì)地址填入GOT表和DATA中。

PLT Hook的執(zhí)行時(shí)機(jī),是在linker將ELF加載到內(nèi)存之后。Hook的原理,是解析內(nèi)存中的ELF數(shù)據(jù),修改relocation結(jié)果。

裝載、動(dòng)態(tài)鏈接、重定位

1. 裝載

使用System.loadLibrary的方式,加載目標(biāo)共享庫,內(nèi)部其實(shí)也是調(diào)用linker中的dlopen、dlsym、dlclose函數(shù)對(duì)目標(biāo)共享庫進(jìn)行裝載。

2. 動(dòng)態(tài)鏈接

動(dòng)態(tài)鏈接的基本思想是把程序按照模塊拆分成各個(gè)相對(duì)獨(dú)立部分,在程序運(yùn)行時(shí)才將它們鏈接在一起。當(dāng)共享庫被裝載的時(shí)候,動(dòng)態(tài)鏈接器linkder會(huì)將共享庫裝載到進(jìn)程的地址空間,并且將程序中的符號(hào)綁定到動(dòng)態(tài)鏈接庫中,進(jìn)行重定位工作。

3. 重定位

共享庫需要重定位的主要原因是導(dǎo)入符號(hào)的存在。動(dòng)態(tài)鏈接下,一旦依賴于其他共享對(duì)象,就會(huì)有導(dǎo)入符號(hào)。這些導(dǎo)入符號(hào)在編譯的時(shí)候是未知的,只有在運(yùn)行的時(shí)候才確定,所以需要就這些導(dǎo)入符號(hào)的引入進(jìn)行修正,即進(jìn)行重定位。

PLT Hook的原理,就是改變導(dǎo)入符號(hào)重定位的結(jié)果。

linker

image.png

linkder在加載ELF時(shí)的最主要工作是relocation,這個(gè)過程的目的是為當(dāng)前ELF的每個(gè)“導(dǎo)入符號(hào)”找到對(duì)應(yīng)的外部符號(hào)(函數(shù)或數(shù)據(jù))的絕對(duì)地址。

這些地址會(huì)寫在以下幾個(gè)地方:

  • .got.plt: GOT表,保存外部函數(shù)的絕對(duì)地址
  • .data, .data.rel.ro:保存外部數(shù)據(jù)(包含函數(shù)指針)的絕對(duì)地址

要完成 relocation 過程,需要依賴于 ELF 中的以下信息:

  • .rel.plt,.rela.plt:用于關(guān)聯(lián) .dynsym 和 .got.plt。這就是我們經(jīng)常會(huì)聽到的 “PLT 表”。
  • .rel.dyn,.rela.dyn,.rel.dyn.aps2,.rela.dyn.aps2:用于關(guān)聯(lián) .dynsym 和 .data,.data.rel.ro。

relocation完成后的函數(shù)調(diào)用關(guān)系如下:


image.png

PLT和GOT表

  • PLT表:程序鏈接表(Procdure Link Table),外部調(diào)用的跳板,.plt
  • GOT表:全局偏移表 (Global Offset Table),記錄外部調(diào)用的入口地址,.got

由上面的分析可知,當(dāng)我們調(diào)用某個(gè)函數(shù)的時(shí)候,并不是直接調(diào)用函數(shù)的地址,而是經(jīng)過PLT表,跳轉(zhuǎn)到GOT表,獲取目標(biāo)函數(shù)的全局偏移。這個(gè)時(shí)候就可以通過基址+偏移的方式。定位到真正的函數(shù)地址。

PLT Hook基本原理

PLT Hook就是改變了原來的relocation后的地址。主要流程:

  • 通過符號(hào)名,在hash table中找到對(duì)應(yīng)的符號(hào)信息
  • 再找到對(duì)應(yīng)的PLT信息
  • 最后找到GOT表中的絕對(duì)地址的值
  • 修改這個(gè)絕對(duì)地址的值,為我們的“代理函數(shù)”的地址
?著作權(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)容

  • 動(dòng)態(tài)鏈接 為什么需要?jiǎng)討B(tài)鏈接 靜態(tài)鏈接使得不同的程序開發(fā)者和部門能夠相對(duì)獨(dú)立的開發(fā)和測(cè)試自己的程序模塊,從某種意義...
    Cool_Pomelo閱讀 1,589評(píng)論 0 3
  • 編譯 一、系統(tǒng)環(huán)境 CPU:Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz 操作...
    delta1037閱讀 629評(píng)論 0 1
  • 第二章 靜態(tài)鏈接 疑問: 問什么靜態(tài)鏈接不會(huì)把所有代碼鏈接進(jìn)程序 為什么要靜態(tài)鏈接 被隱藏的過程 gcc hell...
    杰米閱讀 372評(píng)論 0 0
  • ELF文件布局 relocatable類型(ET_REL)的ELF文件(如.o目標(biāo)文件)無Program Head...
    lbtrace閱讀 2,649評(píng)論 0 2
  • 裝載與動(dòng)態(tài)鏈接 可執(zhí)行文件的裝載與進(jìn)程 每個(gè)程序都擁有自己獨(dú)立的虛擬地址空間,這個(gè)空間大小由計(jì)算機(jī)硬件平臺(tái)決定(理...
    拉普拉斯妖kk閱讀 862評(píng)論 0 1

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