探尋ELF檔案內容,理清符號所在section

2021-06-29 15:28:46 字數 2164 閱讀 7320

採用的程式demo是:

swap.c

extern int buf;

int *bufp0 = &buf[0];

int *bufp1;

void swap()

main.c

#include void swap();

int buf[2] = ;

static int foo = 99;

int f()

int g()

int main()

下面通過命令readelf命令來探尋elf內部。

​可以看到elf頭的一些資訊:採用補碼,小段序;目標檔案的型別是可重定位目標檔案;機器型別是intel80386;elf header的大小是52b;有30個section header,共40b;等等。

可以看到elf中各個section的索引號,起始位址,大小,標誌字段。唯讀資料段15,已初始化全域性變數24,未初始化全域性變數25,符號表28,字串表29,**段13.(其他的現在還不懂)。接下來結合上面的**看符號表資訊。

ndx列表明每個符號所在的段,其中有三個偽段(pseudo section):abs表示不該被重定位的符號,undef表示在本模組引用,卻在其他模組定義,common表示還未分配位置的未初始化物件。

main.c, swap.c代表源檔名,型別是abs。

f, g是在main.c中定義的倆函式,type=func, bind=global, 表示全域性函式,所在的section是13(.text),起始位址分別為80483d4,de,大小都是10b.

變數foo, buf都是初始化的全域性變數,在24號段(.data)中,大小分別是4,8b,不同在於foo有static修飾,所以bind=local,對於buf0,buf1也是類似情況.

特別值得關注的是定義在函式f, g中的有static修飾的同名區域性變數x,在符號表中有唯一的local linker symbols:x.1688, x.1691都在全域性初始化段中,bind=local.

接下來看swap.o的elf資訊:

可以看到型別是可重定位目標檔案。(rel)

與前面readelf -a a.out很大不同的地方在於這裡多了一些.rel.text  .rel.data等可重定位的section,這是有目標檔案的型別決定的,可重定位目標檔案存在的意義就是被鏈結到其他目標檔案中,構建可執行目標檔案,所以就需要在elf中表明哪些符號需要進行位址的修改。呼叫外部函式或者引用全域性變數的指令都需要修改,本地函式呼叫是相對位址,所以不需要修改。上述**段位置列表在這裡顯然表示的就是swap()裡面需要重定位的物件,其中操縱了1次buf符號,3次bufp1, 2次bufp0, 所以出現了對應的條目,並且根據偏移量可以更好的理解。在重定位資料段中就只有我們引用的外部變數buf。

在swap.o的符號表中,bu所在的section是und type=notype,表明其是extern的。bufp0是以初始化的全域性變數,32位系統指標大小是4b,所在的section number是3(.data).特別要注意的是bufp1是未初始化未分配位置的物件,所以ndx=com, value值指明的是對齊要求。

總結:通過以上的分析可以更清晰的理解可執行檔案的記憶體布局, 不同物件所在的section,從而指導自己的程式設計。

ELF檔案 介紹

elf 檔案格式是乙個開放標準,各種unix系統的可執行檔案都採用elf格式,它有三種不同的型別 在這裡先詳細解釋一下程式的彙編 鏈結 執行過程 1 寫乙個匯程式設計序儲存成文字檔案max.s。2 彙編器讀取這個文字檔案轉換成目標檔案max.o,目標檔案由若干個section組成,我們在匯程式設計序...

ELF檔案分析

乙個程式要想執行,首先要載入到記憶體中,程式的pc指標指向記憶體中的 在執行的時候會使用記憶體中的資料。所以elf檔案主要包含 和資料。資料可以分為兩類 靜態資料。動態資料。什麼是動態資料?動態資料程式執行過程中產生,在堆或者棧上分配記憶體。而靜態資料則不然,靜態資料在 編譯完成後,就應該確定使用的...

ELF檔案歸類

elf格式檔案歸為4類 1.型別 說明可重定位檔案 relocatable file 這類檔案包含了 和資料,可以被連線成可執行檔案或共享目標檔案,如linux的.o,windows的.obj 可執行檔案 executable file 這類檔案包含可以直接執行的程式,如 bin bas 件 win...