日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 可执行文件 ELF结构 及程序加载运行

發布時間:2023/11/30 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 可执行文件 ELF结构 及程序加载运行 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?Linux下ELF文件類型分為以下幾種:

????1、可重定位文件,例如SimpleSection.o;

????2、可執行文件,例如/bin/bash;

????3、共享目標文件,例如/lib/libc.so。

????在Linux 可重定位文件 ELF結構一文中,我們已經分析了可重定位文件ELF結構。本文分析可執行文件的ELF結構。

????首先附上源代碼:

????SectionMapping.c?


#include <stdlib.h>
?
int main()
{
?? ?while(1)
?? ?{
?? ??? ?sleep(1000);
?? ?}
?? ?return 0;
}

????使用命令gcc -static?SectionMapping.c -o?SectionMapping.elf,靜態鏈接為可執行文件。

????接著使用命令readelf -S SectionMapping.elf得到Section Table。如下:


There are 33 section headers, starting at offset 0xc3878:

Section Headers:
? [Nr] Name ? ? ? ? ? ? ?Type ? ? ? ? ? ? Address ? ? ? ? ? Offset
? ? ? ?Size ? ? ? ? ? ? ?EntSize ? ? ? ? ?Flags ?Link ?Info ?Align
? [ 0] ? ? ? ? ? ? ? ? ? NULL ? ? ? ? ? ? 0000000000000000 ?00000000
? ? ? ?0000000000000000 ?0000000000000000 ? ? ? ? ? 0 ? ? 0 ? ? 0
? [ 1] .note.ABI-tag ? ? NOTE ? ? ? ? ? ? 0000000000400190 ?00000190
? ? ? ?0000000000000020 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 4
? [ 2] .note.gnu.build-i NOTE ? ? ? ? ? ? 00000000004001b0 ?000001b0
? ? ? ?0000000000000024 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 4
? [ 3] .rela.plt ? ? ? ? RELA ? ? ? ? ? ? 00000000004001d8 ?000001d8
? ? ? ?0000000000000120 ?0000000000000018 ? A ? ? ? 0 ? ? 5 ? ? 8
? [ 4] .init ? ? ? ? ? ? PROGBITS ? ? ? ? 00000000004002f8 ?000002f8
? ? ? ?0000000000000018 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 4
? [ 5] .plt ? ? ? ? ? ? ?PROGBITS ? ? ? ? 0000000000400310 ?00000310
? ? ? ?00000000000000c0 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 6] .text ? ? ? ? ? ? PROGBITS ? ? ? ? 00000000004003d0 ?000003d0
? ? ? ?0000000000094988 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 7] __libc_thread_fre PROGBITS ? ? ? ? 0000000000494d60 ?00094d60
? ? ? ?00000000000000a8 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 8] __libc_freeres_fn PROGBITS ? ? ? ? 0000000000494e10 ?00094e10
? ? ? ?000000000000181c ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 9] .fini ? ? ? ? ? ? PROGBITS ? ? ? ? 000000000049662c ?0009662c
? ? ? ?000000000000000e ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 4
? [10] .rodata ? ? ? ? ? PROGBITS ? ? ? ? 0000000000496640 ?00096640
? ? ? ?000000000001d344 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 32
? [11] __libc_thread_sub PROGBITS ? ? ? ? 00000000004b3988 ?000b3988
? ? ? ?0000000000000008 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [12] __libc_subfreeres PROGBITS ? ? ? ? 00000000004b3990 ?000b3990
? ? ? ?0000000000000058 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [13] __libc_atexit ? ? PROGBITS ? ? ? ? 00000000004b39e8 ?000b39e8
? ? ? ?0000000000000008 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [14] .eh_frame ? ? ? ? PROGBITS ? ? ? ? 00000000004b39f0 ?000b39f0
? ? ? ?000000000000d4c4 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [15] .gcc_except_table PROGBITS ? ? ? ? 00000000004c0eb4 ?000c0eb4
? ? ? ?0000000000000172 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 1
? [16] .tdata ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1ef0 ?000c1ef0
? ? ? ?0000000000000020 ?0000000000000000 WAT ? ? ? 0 ? ? 0 ? ? 16
? [17] .tbss ? ? ? ? ? ? NOBITS ? ? ? ? ? 00000000006c1f10 ?000c1f10
? ? ? ?0000000000000038 ?0000000000000000 WAT ? ? ? 0 ? ? 0 ? ? 16
? [18] .init_array ? ? ? INIT_ARRAY ? ? ? 00000000006c1f10 ?000c1f10
? ? ? ?0000000000000008 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [19] .fini_array ? ? ? FINI_ARRAY ? ? ? 00000000006c1f18 ?000c1f18
? ? ? ?0000000000000008 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [20] .ctors ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1f20 ?000c1f20
? ? ? ?0000000000000010 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [21] .dtors ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1f30 ?000c1f30
? ? ? ?0000000000000010 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [22] .jcr ? ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1f40 ?000c1f40
? ? ? ?0000000000000008 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [23] .data.rel.ro ? ? ?PROGBITS ? ? ? ? 00000000006c1f50 ?000c1f50
? ? ? ?0000000000000080 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 16
? [24] .got ? ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1fd0 ?000c1fd0
? ? ? ?0000000000000010 ?0000000000000008 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [25] .got.plt ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1fe8 ?000c1fe8
? ? ? ?0000000000000078 ?0000000000000008 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [26] .data ? ? ? ? ? ? PROGBITS ? ? ? ? 00000000006c2060 ?000c2060
? ? ? ?0000000000001690 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 32
? [27] .bss ? ? ? ? ? ? ?NOBITS ? ? ? ? ? 00000000006c3700 ?000c36f0
? ? ? ?0000000000002ba8 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 32
? [28] __libc_freeres_pt NOBITS ? ? ? ? ? 00000000006c62b0 ?000c36f0
? ? ? ?0000000000000048 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 16
? [29] .comment ? ? ? ? ?PROGBITS ? ? ? ? 0000000000000000 ?000c36f0
? ? ? ?000000000000002a ?0000000000000001 ?MS ? ? ? 0 ? ? 0 ? ? 1
? [30] .shstrtab ? ? ? ? STRTAB ? ? ? ? ? 0000000000000000 ?000c371a
? ? ? ?000000000000015b ?0000000000000000 ? ? ? ? ? 0 ? ? 0 ? ? 1
? [31] .symtab ? ? ? ? ? SYMTAB ? ? ? ? ? 0000000000000000 ?000c40b8
? ? ? ?000000000000c168 ?0000000000000018 ? ? ? ? ?32 ? 870 ? ? 8
? [32] .strtab ? ? ? ? ? STRTAB ? ? ? ? ? 0000000000000000 ?000d0220
? ? ? ?0000000000007a26 ?0000000000000000 ? ? ? ? ? 0 ? ? 0 ? ? 1
?????????????????????????????????????表 1

????這個可執行文件共有33個Section。

????接著我們使用readelf -h?SectionMapping.elf,讀取elf可執行文件頭部信息。如下圖:

?????????????????????????????????????圖 1

????可以對比,Linux 可重定位文件 ELF結構,這里多了program header。

????Entry point address:程序的入口地址是0x401058,使用objdump -d?SectionMapping.elf | less,可以查看到程序的入口地址是<_start>。如下圖:

???????????????????????????????????????????圖 2

????Start of program headers:program headers的偏移,由于頭文件大小為64,所以program headers緊挨著頭文件存放。

????Size of program headers:program headers的大小。為56個字節。

????Number of section headers:program headers的數量。為6個。

????在表1中,第一個section在文件中的偏移是0x190,頭文件大小為64 + program header大小為56 * program header數量6 = 400 = 0x190。

????然后,我們使用命令readelf -l?SectionMapping.elf,我們會得到program header部分。如下圖:

?????????????????????????????????圖 ?3

????從圖中可見,分為6個Segment。注意表1中每個段叫Section。

????Offset:這個Segment在文件中偏移。

????VirtAddr:這個Segment在虛擬地址的偏移。

????FileSiz:在ELF文件中所占的長度。

????MemSiz:在進程虛擬空間所占的長度。

????我們發現第二個Segment,MemSiz > FileSiz,表示在內存中分配的空間大小超過文件實際大小。超過的部分全部初始化為0,作為BSS段。因為數據段和BSS段的唯一區別是,數據段從文件中初始化內容,BSS段內容全部初始化為0。

????我們主要關心前兩個Segment,第一個是代碼段,虛擬地址從0x00400000到0x004c1026。文件偏移從0x00000000到0x000c1026。

????第二個是數據段,虛擬地址為從0x006c1ef0到0x006c1ef0+0x4408=0x6c62f8。文件偏移從0x000c1ef0到0x000c1ef0+0x1800=0x000C36f0。

????結合表1和兩個Segment的文件偏移,可以得出:

????第一個Segment從第0個Section到第15個Section。(0x00000000-0x000c1026)

? [Nr] Name ? ? ? ? ? ? ?Type ? ? ? ? ? ? Address ? ? ? ? ? Offset
? ? ? ?Size ? ? ? ? ? ? ?EntSize ? ? ? ? ?Flags ?Link ?Info ?Align
? [ 0] ? ? ? ? ? ? ? ? ? NULL ? ? ? ? ? ? 0000000000000000 ?00000000
? ? ? ?0000000000000000 ?0000000000000000 ? ? ? ? ? 0 ? ? 0 ? ? 0
? [ 1] .note.ABI-tag ? ? NOTE ? ? ? ? ? ? 0000000000400190 ?00000190
? ? ? ?0000000000000020 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 4
? [ 2] .note.gnu.build-i NOTE ? ? ? ? ? ? 00000000004001b0 ?000001b0
? ? ? ?0000000000000024 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 4
? [ 3] .rela.plt ? ? ? ? RELA ? ? ? ? ? ? 00000000004001d8 ?000001d8
? ? ? ?0000000000000120 ?0000000000000018 ? A ? ? ? 0 ? ? 5 ? ? 8
? [ 4] .init ? ? ? ? ? ? PROGBITS ? ? ? ? 00000000004002f8 ?000002f8
? ? ? ?0000000000000018 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 4
? [ 5] .plt ? ? ? ? ? ? ?PROGBITS ? ? ? ? 0000000000400310 ?00000310
? ? ? ?00000000000000c0 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 6] .text ? ? ? ? ? ? PROGBITS ? ? ? ? 00000000004003d0 ?000003d0
? ? ? ?0000000000094988 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 7] __libc_thread_fre PROGBITS ? ? ? ? 0000000000494d60 ?00094d60
? ? ? ?00000000000000a8 ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 8] __libc_freeres_fn PROGBITS ? ? ? ? 0000000000494e10 ?00094e10
? ? ? ?000000000000181c ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 16
? [ 9] .fini ? ? ? ? ? ? PROGBITS ? ? ? ? 000000000049662c ?0009662c
? ? ? ?000000000000000e ?0000000000000000 ?AX ? ? ? 0 ? ? 0 ? ? 4
? [10] .rodata ? ? ? ? ? PROGBITS ? ? ? ? 0000000000496640 ?00096640
? ? ? ?000000000001d344 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 32
? [11] __libc_thread_sub PROGBITS ? ? ? ? 00000000004b3988 ?000b3988
? ? ? ?0000000000000008 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [12] __libc_subfreeres PROGBITS ? ? ? ? 00000000004b3990 ?000b3990
? ? ? ?0000000000000058 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [13] __libc_atexit ? ? PROGBITS ? ? ? ? 00000000004b39e8 ?000b39e8
? ? ? ?0000000000000008 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [14] .eh_frame ? ? ? ? PROGBITS ? ? ? ? 00000000004b39f0 ?000b39f0
? ? ? ?000000000000d4c4 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 8
? [15] .gcc_except_table PROGBITS ? ? ? ? 00000000004c0eb4 ?000c0eb4
? ? ? ?0000000000000172 ?0000000000000000 ? A ? ? ? 0 ? ? 0 ? ? 1

????第二個Segment從第16個Section到26個Section。(0x000c1ef0-0x000C36f0)
? [16] .tdata ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1ef0 ?000c1ef0
? ? ? ?0000000000000020 ?0000000000000000 WAT ? ? ? 0 ? ? 0 ? ? 16
? [17] .tbss ? ? ? ? ? ? NOBITS ? ? ? ? ? 00000000006c1f10 ?000c1f10
? ? ? ?0000000000000038 ?0000000000000000 WAT ? ? ? 0 ? ? 0 ? ? 16
? [18] .init_array ? ? ? INIT_ARRAY ? ? ? 00000000006c1f10 ?000c1f10
? ? ? ?0000000000000008 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [19] .fini_array ? ? ? FINI_ARRAY ? ? ? 00000000006c1f18 ?000c1f18
? ? ? ?0000000000000008 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [20] .ctors ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1f20 ?000c1f20
? ? ? ?0000000000000010 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [21] .dtors ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1f30 ?000c1f30
? ? ? ?0000000000000010 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [22] .jcr ? ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1f40 ?000c1f40
? ? ? ?0000000000000008 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [23] .data.rel.ro ? ? ?PROGBITS ? ? ? ? 00000000006c1f50 ?000c1f50
? ? ? ?0000000000000080 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 16
? [24] .got ? ? ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1fd0 ?000c1fd0
? ? ? ?0000000000000010 ?0000000000000008 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [25] .got.plt ? ? ? ? ?PROGBITS ? ? ? ? 00000000006c1fe8 ?000c1fe8
? ? ? ?0000000000000078 ?0000000000000008 ?WA ? ? ? 0 ? ? 0 ? ? 8
? [26] .data ? ? ? ? ? ? PROGBITS ? ? ? ? 00000000006c2060 ?000c2060
? ? ? ?0000000000001690 ?0000000000000000 ?WA ? ? ? 0 ? ? 0 ? ? 32

????以上分析的都是靜態狀態下的程序,下面我們看看動態下的進程的空間是怎么分配的。
????首先使用命令,?./SectionMapping.elf &,輸出如下:

????

????然后使用命令:cat /proc/2184/maps,輸出如下:

????????????????????????????????????圖 4

????

????靜態時,我們計算出的兩個Segment的虛擬空間的偏移分別為:

????第一個是代碼段,虛擬地址從0x00400000到0x004c1026。在圖4中,因為要頁面對齊,所以分配了0x400000到0x4c2000。

????第二個是數據段,虛擬地址為從0x006c1ef0到0x006c1ef0+0x4408=0x6c62f8。在圖4中,因為要頁面對齊,所以分配了0x6c1000到0x6c4000。注意,0x6c62f8大于0x6c4000,具體原因以后再分析。

????第三個緊接著是堆。用于動態分配內存。

????第四個是棧。用于存放局部變量。

????整體的結構如下圖:

????程序運行的過程:建立虛擬空間(分配一個頁目錄)-> 建立虛擬空間與可執行文件映射(頁目錄項指向磁盤的程序) -> 跳到程序入口 -> 缺頁異常-> 在內存中尋找空閑頁,將對應的頁換入 -> 建立映射 -> 開始執行。

原文:https://blog.csdn.net/jltxgcy/article/details/39233689?
?

總結

以上是生活随笔為你收集整理的Linux 可执行文件 ELF结构 及程序加载运行的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。