我又來啦,
今天是本系列介紹
elf檔案的最後一篇教程
.跟隨大家一起了解了
elf檔案的大致結構
.整個結構其實是很明朗的,根據
elf頭
,程式頭,節頭
.從節頭里提取不同的型別
,到不同的節表內去獲取不同的資訊
,今天這裡主要介紹重定位表
.也是常用的節表之一
.有了符號名和動態庫的名字作業系統就可以為我們引入函式了,但在我們的程式中是誰會用這些外部函式呢,系統解析出來的函式位址應該給誰呢?這就是重定位表的功勞了!
重定位表的型別有兩種sht_rel
和sht_rela,我們只談sht_rel.
[cpp]view plain
copy
typedef
struct
elf32_rel;
重定位表其實很簡單,它的r_offset成員給出了需要重定位內容的位址,而它的r_info欄位給出了兩條資訊,一條是與此重定位內容相關的符號
,一條是重定位的型別,在
elf.h
中分別有
[cpp]view plain
copy
#define elf32_r_sym(val) ((val) >> 8)
#define elf32_r_type(val) ((val) & 0xff)
#define elf32_r_info(sym, type) (((sym) << 8) + ((type) & 0xff))
從成員r_info中獲取符號資訊和重定位資訊,符號資訊就是乙個符號表的索引
,32位下占用這個成員的高24位
,剩餘的
8位就是重定位型別了
.符號資訊就是乙個符號表中的索引.
在i386
上從外部引入的動態函式重定位型別是
r_386_jmp_slot.由這個型別的名稱可以看出動態連線在linux
上是處理器密切相關的東西.剛說r_info
字段包含了乙個符號表中的索引,對於從外部引入的動態函式來說那個符號表就是
「動態符號表
」,它在節頭結構中的型別值為
sht_dynsym
。r_offset
欄位是乙個位址,載入之初被
r_offset
指向的內容
——也就是乙個外部符號的位址
——並不正確,作業系統就根據重定位資訊引用的符號找到那個位址,然後修改
r_offset
所指向的內容。這部分我們在第五講中已經得到證實,發現
got表內的位址並不是真正的函式位址入口
.這就是因為
linux的"
懶模式"機制.
下面給出**:
[cpp]view plain
copy
#include "readrel.h"
void
display_rel(elf32_ehdr *ehdr,elf32_shdr *shdr)
} void
displayrel(elf32_ehdr *ehdr,elf32_shdr *shdr)
shdr++;
} }
前面我們講了,
怎麼手動通過
gdb攔截
printf引數,
下一節,
我們將通過程式來攔截
printf
的引數,
使之永遠都輸入我們給定的字串
.盡情期待...
謝謝~~~~
我也是菜鳥.
一起努力學習.再見
一步一步走進Docker
docker命令 啟動sudo service docker start 檢視映象 docker images 檢視當前映象 docker ps 進入映象 docker run i t tomcat 1 bin bash 目錄對映 sudo docker run i t v data softwar...
一步一步走進Linux HOOK API 四
這一節主要是講述的是符號節.要怎麼才能找到符號節呢 其實只要在上一期講的遍歷節頭的時候 判斷每乙個節型別是不是sht symtab或 sht dynsym,那麼相應的節就是乙個符號節了 符號節存放的是一張符號表 符號表也是乙個連續儲存的結構陣列 那什麼叫符號呢?程式設計過程中用到的變數和函式都可以稱...
一步一步 Sql Azure
一步一步 sql azure 1.使用 windowsazure 平台賬號登陸 2.新建sqlazure server 3.新建資料庫 4.為sql azure server 新增防火牆規則,只有將本機新增到規則裡才能從本機連線到該sqlazure server 5.連線到sql azure ser...