[英]ELF Program Headers and Virtual Address
我正在了解 ELF 及其程序頭文件。 當我使用文件類型為 DYN 的readelf
讀取 ELF 時。 我看到 Program Headers 中的虛擬地址值實際上來自 kernel 虛擬地址空間。
Elf file type is DYN (Shared object file)
Entry point 0x1060
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000600 0x0000000000000600 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x00000000000001f5 0x00000000000001f5 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000168 0x0000000000000168 R 0x1000
LOAD 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8
0x0000000000000258 0x0000000000000260 RW 0x1000
DYNAMIC 0x0000000000002dc8 0x0000000000003dc8 0x0000000000003dc8
0x00000000000001f0 0x00000000000001f0 RW 0x8
NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358
0x0000000000000044 0x0000000000000044 R 0x4
GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
GNU_EH_FRAME 0x0000000000002018 0x0000000000002018 0x0000000000002018
0x0000000000000044 0x0000000000000044 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8
0x0000000000000248 0x0000000000000248 R 0x1
我能夠在加載二進制文件時推斷出實際的 VirtAddr 應該是 = Base Address + VirtAddr。 但我無法找出加載程序如何計算基地址值?
另外,我知道 .text 和 .data 是用於加載二進制文件的兩個 PT_LOAD 段。 但我在示例中看到了 4 個 PT_LOAD 程序頭。 兩個 PT_LOAD 程序頭是做什么用的?
我看到 Program Headers 中的虛擬地址值實際上來自 kernel 虛擬地址空間。
不,你沒有看到。 output 中的所有地址都與 kernel 無關。
您正在查看的是一個Position 獨立可執行文件,可以在 memory 的任何位置加載。
我無法找出加載程序如何計算基地址值?
加載器不加載主可執行文件(kernel 加載),也不決定加載地址。
鑒於文件類型是ET_DYN
,kernel 執行等效於mmap(0, ...)
(沒有MAP_FIXED
標志),並選擇合適的虛擬地址,然后在aux
向量中與加載程序通信。
但我在示例中看到了 4 個 PT_LOAD 程序頭。 兩個 PT_LOAD 程序頭是做什么用的?
看到這個答案。
這不是一個設置基地址的程序。 相反,它是一個與位置無關的可執行文件,可以鏈接到 memory 中的任何地址,從而實現地址空間布局隨機化,即 ALSR。
它與普通共享庫的區別在於它具有程序解釋器集,通常共享庫沒有...
這里最低的虛擬 memory 地址正好是0x0000000000000040
,對應文件偏移量0x0000000000000040
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.