簡體   English   中英

ELF 程序頭和虛擬地址

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM