美文网首页
操作系统(2)---- 可执行文件布局

操作系统(2)---- 可执行文件布局

作者: 特立独行的佩奇 | 来源:发表于2021-10-31 09:16 被阅读0次
静态布局和动态布局

这里分析可执行文件,静态布局是指可执行文件在存储器上的内部结构,
动态布局是指程序被加载到内存上的动态布局

可执行文件包含包含了程序编译形成的指令和数据,这是对可执行文件的粗略的理解,这里我会更加详细的探究其内部

Linux 中,可执行文件的标准是 ELF(Excutable and Linkable Foramt)格式

ELF的静态布局

ELF文件结构包含一个固定长度的文件头和多个可以拓展的数据块
文件头是可执行文件总地图,描述了整个文件的组织结构
数据块分为两种视图 如下图所示:


链接视图和执行视图.png
  • 链接视图下,数据块的单位是节(section), 用节区头索引其他内容
  • 执行视图下,数据块的单为是段(segment), 用程序头索引所有的段

下面以一个在 Ubuntu 上用gcc 编译出来的ELF文件为例,剖析一下bin文件的内部

ELF 头文件

使用 readelf -h 可以读取ELF 头文件的内容


ELF_header.png

• 生成的可执行文件的大小是 6836 字节,文件格式是 64 位的 Linux 标准可执行文件(ELF 64-bit LSB Executable),目标平台是 x86-64。
• 程序的入口地址是 0x770,该文件的 ELF 头的大小是 64 字节。
• 文件中有 9 个 Program Header,每个 Program Header 的长度是 56 字节 ,信息存放在从文件头算起 56 字节的位置。
• 另外还有 35 个 Section Header,每个 Section Header 的大小是 64 字节,信息位于从文件头算起 14592 字节的位置。

程序头和节区头

使用 readelf -S 读取ELF文件的节区头信息


ELF_sectionheader.png

Type : 表示节区的类型
Address: 表示该节区占用虚拟内存的起始地址
Offset: 该节区在可执行文件中的存放位置
Size: 节区

使用 readelf -l 命令读取bin文件的程序头表信息


ELF_programeheader.png

表示该可执行文件有九个段,并且列出了每个段在文件中的起始地址(Offset 列)、程序加载后占据的虚拟地址(VirtAddr 列)、物理地址(PhysAddr 列)、在文件中占据的空间大小(FileSiz 列)、在内存中占据的空间大小(MemSiz 列)等信息,另外,还列出了节区与段的映射关系,指出了哪些节区在运行时会归入哪个段。

其他分析指令

objdump -s -j sectionName dump ELF 文件 section 内容
比如: objdump -s -j .rodata demobin 可以dump出 demobin 的 rodata 节区

静态布局总结

到这里,ELF文件的静态布局就已经分析完了,我们可以在总结一下,可执行文件从前到后依次为 ELF文件头,程序头表,多个节区,节区头表,最后编译系统还会附加.symtab 和 .strtab 节区

影响静态布局的因素
.text 节区

.text 节区存放的是程序源码编译后产生的机器指令,所有的程序逻辑都会存放在这里
编译时可以添加优化选项,使用 -O1 优化选项编译程序可以生成尽量紧凑的 .text 节区,而用 -O2 优化选项会使编译器倾向于生成执行速度更快的指令组合,但有可能让 .text 节区的体积轻微地增大。

.rodata 节区

存储了程序中的常量数据,比如下面的常量数组
比如下面的语句:
const char ptr[] = "demo data tdebug";
会最终编译到.rodata 段


ELF_rodata.png

程序运行的时候 .rodata 和 .text section 都会被加载到相同的 segment 中,它们的权限只有读和执行,如果强制写会触发 segment fault 错误.
但需要注意的是,只有静态和全局的 const 数据才能享受这样的待遇,如果在函数内部声明 const value, 其本质上还是一个函数内的局部变量,存储区在该函数的栈帧内,而程序对该内存区拥有修改的权限。

.data 节区

存放全局和静态的已经初始化的变量,比如下面的语句:
char ptr[] = "demo data tdebug";
使用objdump 验证:


ELF_data.png
.bss 节区

该节区存储了所有未初始化或初始化为 0 的全局和静态变量

.got和 .glt 节区

这两个节区存储了动态链接用到的全局入口表和跳转表。当程序中用到动态链接库中的某个函数时,会在该节区内记录相应的数据

相关文章

  • 操作系统(2)---- 可执行文件布局

    静态布局和动态布局 这里分析可执行文件,静态布局是指可执行文件在存储器上的内部结构,动态布局是指程序被加载到内存上...

  • Servlet & JSP学习笔记之简介

    前言 对于Java程序而言: JVM >> 操作系统 class文件 >> 可执行文件 Web容器 Web容器可以...

  • 第12章 PE文件格式

    1. 介绍 PE文件是Window操作系统下使用的可执行文件格式.PE文件是指32位的可执行文件,也称为PE32...

  • python学习干货教程(2):环境变量配置

    程序和可执行文件可以在许多目录,而这些路径很可能不在操作系统提供可执行文件的搜索路径中。 path(路径)存储在环...

  • Java学习day-20:多线程

    一、程序、进程、线程 1.程序Program: 是一个静态的概念,一般对应于操作系统中的一个可执行文件。 2.进程...

  • 编程学习(一) 基本数据类型

    程序的执行过程:编译器将我们的程序编程成可执行文件,然后操作系统将我们的可执行文件全部装载到内存中,接着CPU从入...

  • 逆向 - PE结构详解

    PE(Portable Executable)文件简介 PE文件是Windows操作系统下使用的可执行文件格式。它...

  • linux(3) 系统目录架构

    bin binary 缩写,保存可执行文件,也就是命令, boot 引导目录,操作系统的启动的文件,里面有...

  • Windows逆向分析及外挂制作必备知识之PE结构简析

    可执行文件格式是操作系统本身执行进制的反映,可执行文件可以是具有不同格式的二进制文件,也可以是一个文本的脚本。...

  • dll和so文件区别与构成

    动态链接,在可执行文件装载时或运行时,由操作系统的装载程序加载库。大多数操作系统将解析外部引用(比如库)作为加载过...

网友评论

      本文标题:操作系统(2)---- 可执行文件布局

      本文链接:https://www.haomeiwen.com/subject/bbqoaltx.html