浅谈ELF的认识
目錄
- 一、引入ELF
- 1.1 第一個視角先了解點基礎的知識
- 1.2 第二個視角先了解點基礎的知識
- 二、 介紹 ELF
- 三、應用
一、引入ELF
1.1 第一個視角先了解點基礎的知識
??當我們創建一個Hello.c文件后,會使用gcc命令編譯運行生成一個a.out的可執行文件,但是在這背后還隱藏了許多的動作,有了這個動作的支持,我們最終才可以生成一個可執行文件。我們先看一個hello.c文件到a.out文件中間發生了什么?
圖來自 原文章
背后邏輯簡述:(引入名詞:目標文件 與 動態庫)
??匯編器將匯編語言翻譯為機器語言,生成一個可重定位目標文件,該文件作為輸入傳入到連接器,連接器生成一個 可執行目標文件。該可執行目標文件加載到存儲器里供系統調用,系統就一步步提取我們程序的指令,分配進程。
??以我們程序的printf函數為例子,這個函數存在與printf.o 的函數庫里。要調用printf函數,兩個方式:
-
1 ) 在編譯鏈接時,把庫函數printf.o的全部信息加載到可執行文件里面(代價就是使得可執行文件比較大,但是運行的時候不需要再次調用庫函數)生成后綴為 .a 的文件;
-
2 ) 在編譯鏈接時不發生操作,只在運行時鏈接庫函數(可以節省資源開支,gcc默認)生成后綴為 .so 的文件;
??正式一點,我們將這兩種方式命名為:靜態庫與動態庫,gcc默認采用動態庫
目標文件:
-
可重定位目標文件(.o) (Executable File)
? 包含代碼和數據,是可以直接運行的程序。其代碼和數據都有固定的地址 (或相對于基地址的偏移 ),系統可根據這些地址信息把程序加載到內存執行。 -
可執行目標文件(.out) (Relocatable File)
?包含基礎代碼和數據,但它的代碼及數據都沒有指定絕對地址,因此它適合于與其他目標文件鏈接來創建可執行文件或者共享目標文件。 -
共享目標文件(.so) (Shared Object File)
? 也稱動態庫文件,包含了代碼和數據,這些數據是在鏈接時被鏈接器(ld)和運行時動態鏈接器(ld.so.l、libc.so.l、ld-linux.so.l)使用的。
1.2 第二個視角先了解點基礎的知識
??從第一個視角的介紹中,我們了解到一個文件從被創建到運行具體的流程,探究了它背后的一些秘密,然而我們為什么要知道這些呢,接下來就從宏觀的角度從操作系統的角度介紹一下ELF文件的作用,我們的理解不應該局限于個別的場景。
操作系統 概念中介紹到:
??當很多條的進程在同時請求資源,但是物理內存只有4GB,于是引用虛擬內存通過特定的置換算法轉化為物理內存,使得程序可以正常運作。
我們運行一個程序時候,
1.用戶請求運行程序時,操作系統會讀取存儲在磁盤上的可執行文件,在linux系統上這個文件就是我們的 elf格式文件,為用戶分配4G的虛擬內存空間,2. 根據文件的信息指示,把不同的文件內容放到為你分配的這3G虛擬內存3. 然后根據文件的指示,系統設置設置代碼段和數據段寄存器4.然后根據文件的指示, 跳轉到用戶的代碼的入口地址(一般就是我們的main函數)二、 介紹 ELF
??現在我們已經知道了一個可執行文件產生背后的簡單邏輯,在不同的系統平臺上面,可行性文件的叫法也不一致,在Unix和X86-64 Linux上稱為ELF(Executable and Linkable Format, ELF),正如目標文件有上述三類一樣,ELF也會有上述三個文件分類(不同名字而已,內容一致)
(現在我們已經知道了如何從無到有一個ELF文件,下面了解一下ELF具體的內容吧)
EIF文件結構
首先,ELF文件格式提供了兩種視圖,分別是鏈接視圖和執行視圖。簡易圖:
標準參考圖:
??ELF文件由4部分組成,分別是ELF頭(ELF header)、程序頭表(Program header table)、節(Section)和節頭表(Section header table)。
??實際上,一個文件中不一定包含全部內容,而且它們的位置也未必如同所示這樣安排,只有ELF頭的位置是固定的,其余各部分的位置、大小等信息由ELF頭中的各項值來決定。
節區頭部表(Section Header Table)包含了描述文件節區的信息,比如大小、偏移等。
section表,對可執行文件來說,沒有用,在鏈接的時候有用,是對代碼段數據段在鏈接是的一種描述。
數據段和代碼段最重要
????
| OK,ELF表基本結構已經了解到了,接下來看看怎么使用命令調用查看信息 |
三、應用
在Linux下,我們可以使用 readelf 命令工具可以查看ELF格式文件的一些信息
接下來我們來看Section Header Table格式
用hexdump或者使用010 Editor工具把目標文件的字節全部打印出來看
定位到.text的范圍,然后將這個表編碼
3.3 .text節
通過使用objdump工具可以把程序中的機器指令進行反匯編得到其匯編代碼
草,我寫不下去了,
總結
- 上一篇: 【Java】不可变类(immutable
- 下一篇: python 微信公众号接口中文乱码问题