ELF binary 透過 PLT(Procedure Linkage Table) 與 GOT(Global Offset Table) 達到延遲繫結來減少編譯所消耗的時間
基本上就是在 runtime 需要用到該函數時,再將該函數"找"出來
Global Offset Table
GOT 分為兩部分 .got 與 .got.plt
前者用來存放全域變數引用位置,後者存放函式引用位置
.got.plt
前三項有特別用途
.dynamic 位置
link_map
- 有引用到的 libary 串成的 linked list
dl_runtime_resolve
後面的就是其他函式,未修正的話位址會指向 PLT 表的第二條指令
已修正過後就會直接指向正確的函式位址
Procedure Linkage Table
PLT 是由程式中有用到的函式組成的表
開頭的 PLT[0] 由兩條指令組成
push *(GOT+4) # 將 link_map 壓入 stack
jmp *(GOT+8) # jump 到 runtime_resolver
結束之後就會將正確的函式位址寫回 .got.plt
Lazy binding
舉個解析 puts 的例子
解析前的呼叫流程
解析後的呼叫流程
Conclusion
既然GOT可以在runtime時被修正,那就代表那裏是可讀寫的,可以透過其他弱點改寫GOT,來達到 GOT hijacking,但其實最大的坑是 runtime_resolve …