Linux下ELF文件类型分为以下几种:

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

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

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

在Linux 可重定位文件 ELF结构一文中,我们已经分析了可重定位文件ELF结构。本文分析可执行文件的ELF结构。

首先附上源代码:

SectionMapping.c

#include

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。

我们主穴ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq52NDEx7DBvbj2U2VnbWVudKOstdrSu7j2yse0+sLrts6jrNDpxOK12Na3tNMweDAwNDAwMDAwtb0weDAwNGMxMDI2oaPOxLz+xqvSxrTTMHgwMDAwMDAwMLW9MHgwMDBjMTAyNqGjPC9wPjxwPiAgICC12rb+uPbKx8r9vt22zqOs0OnE4rXY1rfOqrTTMHgwMDZjMWVmMLW9MHgwMDZjMWVmMCsweDQ0MDg9MHg2YzYyZjiho87EvP7Gq9LGtNMweDAwMGMxZWYwtb0weDAwMGMxZWYwKzB4MTgwMD0weDAwMEMzNmYwoaM8L3A+PHA+ICAgIL3hus+x7TG6zcG9uPZTZWdtZW50tcTOxLz+xqvSxqOsv8nS1LXDs/ajujwvcD48cD4gICAgtdrSu7j2U2VnbWVudLTTtdowuPZTZWN0aW9utb212jE1uPZTZWN0aW9uoaOjqDB4MDAwMDAwMDAtMHgwMDBjMTAyNqOpPC9wPjxwPjxwcmUgY2xhc3M9"brush:java;"> [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。

第二个是数据段,虚拟地址通ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq00zB4MDA2YzFlZjC1vTB4MDA2YzFlZjArMHg0NDA4PTB4NmM2MmY4oaPU2s28NNbQo6zS8s6q0qrSs8PmttTG66Osy/nS1LfWxeTByzB4NmMxMDAwtb0weDZjNDAwMKGj16LS4qOsMHg2YzYyZji089PaMHg2YzQwMDCjrL7fzOXUrdLy0tS689TZt9bO9qGjPGJyIC8+PC9wPjxwPiAgICC12sj9uPa99L3T18XKx7bRoaPTw9Patq/MrLfWxeTE2rTmoaM8L3A+PHA+ICAgILXay8S49srH1buho9PD09q05rfFvtayv7Hkwb+hozwvcD48cD4gICAg1fvM5bXEveG5ucjnz8LNvKO6PC9wPjxwPjxpbWcgc3JjPQ=="http://www.it165.net/uploadfile/files/2014/0918/20140918191119351.png" alt="" />

程序运行的过程:建立虚拟空间(分配一个页目录)-> 建立虚拟空间与可执行文件映射(页目录项指向磁盘的程序) -> 跳到程序入口 -> 缺页异常-> 在内存中寻找空闲页,将对应的页换入 -> 建立映射 -> 开始执行。

linux运行vb程序,Linux可执行文件ELF结构及程序加载运行相关推荐

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

    Linux下ELF文件类型分为以下几种: 1.可重定位文件,例如SimpleSection.o: 2.可执行文件,例如/bin/bash: 3.共享目标文件,例如/lib/libc.so. 在Linu ...

  2. Linux下编译、链接、加载运行C++ OpenCV的两种方式及常见问题的解决

    Linux下编译.链接.加载运行C++ OpenCV的两种方式及常见问题的解决 在Linux下安装完OpenCV C++之后(还没有安装的读者请参考Ubuntu 18.04 安装OpenCV C++) ...

  3. Linux下的静态库、动态库和动态加载库

    from: http://www.techug.com/linux-static-lib-dynamic-lib 库的存在极大的提高了C/C++程序的复用性,但是库对于初学者来说有些难以驾驭,本文从L ...

  4. linux磁盘 分区 物理卷 卷组 逻辑卷 文件系统加载点操作案例

    转自:truemylife.linux磁盘 分区 物理卷 卷组 逻辑卷 文件系统加载点操作案例 基本概念: 磁盘.分区.物理卷[物理部分] 卷组[中间部分] 逻辑卷.文件系统[虚拟化后可控制部分] 磁 ...

  5. linux系统把驱动编译成.ko模块 insmod动态加载

    介绍: Linux 驱动有两种运行方式,第一种就是将驱动编译进 Linux 内核中,这样当 Linux 内核启动的时候就会自动运行驱动程序.第二种就是将驱动编译成模块(Linux 下模块扩展名为.ko ...

  6. JavaME程序 Run Anywhere-- 利用反射机制来动态加载声

    让JavaME程序 Run Anywhere-- 利用反射机制来动态加载声 时间:2008-02-23 09:26来源:互联网 让JavaME程序 Run Anywhere -- 利用反射机制来动态加 ...

  7. html下拉刷新原理,微信小程序 下拉刷新及上拉加载原理解析

    这篇文章主要介绍了微信小程序 下拉刷新及上拉加载实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.下拉刷新的概念及应用场景. 概念: 下拉 ...

  8. 微信小程序开发——设置默认图片、错误加载图片

    wxml: <image src='{{imgArr[index]==""?defaultImg:imgList[index]}}' binderror="erro ...

  9. 【微信小程序】实现小程序下拉刷新与上拉加载

    微信小程序内置的上拉加载.下拉刷新与Android原生的有所不同,Android原生下拉刷新用SwipeRefreshLayout组件,重写onRefresh方法,而上拉加载则是使用RecycleVi ...

最新文章

  1. 链mysql_mysql 版本链机制 readView
  2. Laravel5中Cookie的使用
  3. (转) mysqldumpslow使用说明总结
  4. 科目三大路考8个驾驶技巧
  5. eureka常见错误
  6. Mac用户如何在Deckset中使用Ulysses?
  7. 17. CSS 框模型概述
  8. pytorch中hook的使用
  9. 设计模式那点事读书笔记(3)----建造者模式
  10. 首届魔都ArchData技术峰会进入倒计时
  11. 【车间调度】基于matlab NSGA-2算法求解多目标车间调度问题【含Matlab源码 071期】
  12. MySQL与Oracle的DDL、DML语法对比(含可重复执行SQL脚本编写方式)
  13. python win32api教程_Python win32api.GetSystemMetrics方法代码示例
  14. imx8qm xen 虚拟网卡
  15. 数字货币期货生存指南
  16. pth文件转为onnx格式
  17. Java实现生成并下载Excel文件
  18. turtle画等腰三角形
  19. sw2014计算机配置,solidworks配置要求高吗,solidworks需要什么样的电脑配置
  20. DES算法和MAC算法总结

热门文章

  1. 【GNURadio实验报告】实验2-使用GNURadio仿真OOK信号
  2. 毕业论文写作中致谢词的常见写法及优秀范文
  3. 电脑打字技巧:微软输入法的U模式和V模式,快速打日期和时间。
  4. MATLAB-mesh/ezmesh函数三维图形绘制
  5. 使用python爬取12306上面所有车次数据
  6. 数据库表的软硬关联_Jimmy的关系型数据库设计心得 第一版
  7. 【安全】Web指纹识别
  8. 浅谈PHP与Java之Web开发整合技术
  9. 985高校博士因文言文致谢走红!导师评价其不仅SCI写得好...
  10. scratch python插件_scratch插件开发文档