ELF文件格式

2023-11-18

在介绍ELF格式之前,先简单说明一下可执行文件的生成流程:1)编写C源文件,或汇编源文件;2)准备共享库格式的目标文件(shared object file),如数学库、标准库;2)用编译器(compiler)将C编译成可重定位格式的目标文件(relocatable object file),用汇编器(assembler)将汇编源文件编译成可重定位格式的目标文件;3)用连接器(linker)将第二步的共享个库文件和第三步生成的目标文件链接生成可执行文件(executable file)。

(也就是说,内存中程序存在的状态就是ELF格式,当自己编写某个程序,定义指针*p,则p+4的地址为p的地址加4,其实已经在编译时确定了p+4的大小,所以打印出来的地址是+4的,不出错,我yazhouren09的理解)

ELF(excutable and linking format)是一种可执行可链接格式的二进制文件,它可以用来表示relocatable file、executable file或者shared object file,这三者都是目标文件(object file)。所谓“可执行”指可以被调入内存供CPU直接运行;“可链接”指多个ELF格式的目标文件可以被链接在一起形成一个可执行文件。下图左边是可链接格式的ELF文件格式,右边是可执行格式的ELF文件格式。

无论是linking view还是execution view的ELF文件,他们都包含一个ELF Header,它包含文件的基本信息。ELF自定义了一些类型,并强制规定了他们所占的字节个数,以实现跨平台,如Elf32_Half占2字节、Elf32_Word占4字节、Elf32_Off占4字节等。


 1 typedef struct
 2 {
 3 unsigned char     e_ident[EI_NIDENT];     /* Magic number and other info */
 4 Elf32_Half        e_type;                  /*目标文件类型 */
 5 Elf32_Half        e_machine;               /*Architecture */
 6 Elf32_Word       e_version;               /* Object file version */
 7 Elf32_Addr       e_entry;                  /*入口地址 */
 8 Elf32_Off        e_phoff;                  /* Program header table文件偏移 */
 9 Elf32_Off        e_shoff;                  /* Section header table 文件偏移 */
10 Elf32_Word      e_flags;                  /* Processor-specific flags */
11 Elf32_Half       e_ehsize;                 /* ELF header 大小 */
12 Elf32_Half       e_phentsize;              /*每个Program header大小 */
13 Elf32_Half       e_phnum;                /*一共多少个Program header */
14 Elf32_Half       e_shentsize;             /* 每个Section header大小 */
15 Elf32_Half       e_shnum;               /*一共多少个 Section header */
16 Elf32_Half     e_shstrndx;     /*Section的字符表在section header table的索引值 */
17 } Elf32_Ehdr;
18
复制代码
e_ident[EI_NIDENT]是一个有16个字节的数组,e_ident[0]=0x7f,e_ident[1]=”E”,e_ident[2]=”L”, e_ident[3]=”F”, e_ident[4]指示ELFCLASS(0:ELFCLASSNONE;1:ELFCLASS32;2:ELFCLASS64),e_ident[5]指示程序中的数据格式(0:无效;1:小端;2:大端),e_ident[6]指示版本固定为0x1,e_ident[7]到e_ident[14]固定为0,e_ident[15]固定为16用于指示e_ident[]数组有16个元素。e_type指示该ELF文件的类型,占2字节,可以为ET_NONE(0, No file type)/ ET_REL(1, Relocatable file)/ ET_EXEC(2, Executable file)/ ET_DYN(3, Shared object file)/ ET_CORE(4, Core file)/ ET_LOPROC(0xff00, Processor-specific)/ ET_HIPROC(0xffff, Processor-specific),常见的是ET_EXEC、ET_DYN、ET_REL。e_machine定义CPU的指令集架构,ELF标准中定义的有EM_NONE(0)/ EM_M32(1)/ EM_SPARC(2)/ EM_386(3)/ EM_68K(4)/ EM_88K(5)/ EM_860(6)/EM_MIPS(7),其它的值保留,有用户使用,比如EM_OR32=0x8472。e_version定义该ELF文件的版本号。e_entry定义程序的启动地址,也即CPU启动后读取的第一条指令所在的地址。e_phoff定义代表Program header table的数据结构在文件中的以字节为单位的偏移量,为0表示没有Program header table。e_shoff定义代表Section header table数据结构在文件中的以字节为单位的偏移量,为0表示没有Section header table。e_flags定义了和CPU相关的一些参数,不同的CPU对e_flags的定义是不一样的。e_ehsize定义ELF header这个数据结构的以字节为单位的实际大小,之所以出现这个参数,是因为各个平台上ELF自定义类型所表示的字节数不同。一个Program header table包含多个entry即多个Program header,每个entry的占用的文件字节数相同,e_phentsize定义了每个entry的大小,e_phnum定义当前Program header table中entry的个数。一个Section header table包含多个entry即多个Section header,每个entry的占用的文件字节数相同,e_shentsize定义了每个entry的大小,e_shnum定义当前Section header table中entry的个数。在Section header table中有一个特殊的entry,它定义了Section header table中各个entry的名字,e_shstrndx用于指示这个特殊的entry在Section header table中的索引,即它在第几个entry,这个特殊的entry称为section name string table。
Code
复制代码

前面已经提到,Section header table有多个entry,其实每个entry都是一个Elf32_Shdr类型数据结构,用这个数据结构可以找到每个Section在文件中的位置,e_shentsize=sizeof(Elf32_Shdr),e_shnum=numof(Elf32_Shdr)。sh_name是一个字符串数组的索引,它指示当前Section header所描述的这个Section的名字在Section name string table中的位置。sh_type指示当前Section header的类型,SHT_NULL(0,该Section header所指示的section无效,不占用文件空间)/ SHT_PROGBITS(1,该Section header所指示的section包含程序指令)/ SHT_SYMTAB(2,该Section header所指示的section包含重定位符号表)/ SHT_STRTAB(3,该Section header所指示的section包含字符表)/ SHT_RELA(4,重定位相关,用于链接过程)/ SHT_HASH(5,重定位相关,用于链接过程)/ SHT_DYNAMIC(6,用于链接过程)/ SHT_NOTE(7,信息说明)/ SHT_NOBITS(8,,该Section header所指示的section不占用文件字节,除此之外和SHT_PROGBITS含义相同) /SHT_REL(9,重定位相关)/ SHT_SHLIB(10,保留类型)/ SHT_DYNSYM(11,重定位相关)/ SHT_LOPROC(0x70000000)- SHT_HIPROC(0x7fffffff)(这一范围的类型值跟CPU相关)/ SHT_LOUSER(0x80000000)- SHT_HIUSER(0xffffffff)(这一范围的类型值保留给应用程序)。sh_flags指示当前Section header所对应的section的属性,WRITE(0x1,当前Section header所对应的section包含可写的数据)/ALLOC(0x2,当前Section header所对应的section在程序执行时占用实际的存储空间)/EXECINSTR(0x4,当前Section header所对应的section包含可执行的指令)/MASKPROC(0xf0000000,保留)。sh_addr指示当前Section header所对应的section在内存中起始地址。sh_offset指示当前Section header所对应的section在文件中以字节为单位的偏移量。sh_size指示当前Section header所对应的section在文件中占用的字节数。sh_link和sh_info供链接器使用。sh_addralign指示对sh_addr的对其要求。有一些特殊的section,它内部仍然包含多个entry,每个entry大小相同,如symbol table,sh_entsize用于指示这个特殊的section中每个entry的大小。

Code
复制代码

上表列出了一些常见的section。.bss中,包含未初始化的全局数据变量,这些变量不占用ELF文件的空间(SHT_NOBITS),但占用实际内存空间(SHF_ALLOC),在程序运行启动时由OS负责初始化为0。.comment包含版本控制信息。.data和.data1包含已经初始化的全局数据变量,这些变量占用ELF文件空间,也占用实际内存空间。.fini包含主函数退出时执行的指令。.init包含主函数执行前所执行的指令。.rodata和.rodata1包含只读数据。.shstrtab包含section header string table。.text包含程序指令。

typedef struct
{
Elf32_Word     p_type;      /* Segment type */
Elf32_Off       p_offset;      /* Segment offset in file */
Elf32_Addr    p_vaddr;      /* Segment virtual address in memory*/
Elf32_Addr     p_paddr;      /* Segment physical address */
Elf32_Word     p_filesz;      /* Segment size in file */
Elf32_Word     p_memsz;     /* Segment size in memory */
Elf32_Word     p_flags;       /* Segment flags */
Elf32_Word     p_align;      /* Segment alignment */
} Elf32_Phdr;
复制代码
 

前面已经提到,Program header table有多个entry,其实每个entry都是一个Elf32_Phdr类型数据结构,用这个数据结构可以找到每个Segment在文件中的位置,e_phentsize=sizeof(Elf32_Phdr),e_phnum=numof(Elf32_Phdr),每个Segment包含若干个section,只有对executable file和shared object file才能存在Program header。p_type指示当前Program header所指的Segment的类型,PT_NULL(0,指示无效的segment)/ PT_LOAD(1,指示当前Program header所指的Segment须加载到内存中执行)/ PT_DYNAMIC(2)/ PT_INTERP(3)/ PT_NOTE(4)/ PT_SHLIB(5)/ PT_PHDR(6)/PT_LOPROC(0x70000000)/PT_HIPROC(0x7fffffff)。p_offset指示Program header所指的Segment在文件中偏移量。p_vaddr指示Program header所指的Segment在内存中的虚拟地址。p_vaddr指示Program header所指的Segment在内存中的物理地址,一般可忽略。p_filesz指示Program header所指的Segment在文件中的大小。p_memsz指示Program header所指的Segment在内存中的大小,一般地,p_memsz>=p_filesz,对p_filesz不足的内存区域填0。

来源:http://www.cnblogs.com/brianhxh/archive/2009/07/04/1517020.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ELF文件格式 的相关文章

  • 在 Rails 中使用回形针进行 ajax 上传的简单方法?

    我想知道是否有一个简单的方法 例如一个插件 用回形针在 Rails 中进行 ajax 上传 还是我必须从头开始构建它 Cheers 编辑 另外 我正在寻找非闪存解决方案 你可以试试remotipart http os alfajango c
  • php:将变量内容下载为文件

    题主可以吗 我有一个正在执行的脚本 有一次 我在变量中有一大段文本 我可以将其作为可下载文件提供 而不实际将变量内容写入磁盘吗 如果您的意思是让用户单击链接并弹出一个对话框以将某些内容保存为文本文件
  • Internet Explorer 8 不会修改打印样式表中的 HTML5 标记

    我之前正在制作打印样式表 并遇到了 IE8 的问题 我正在使用 HTML5 和几个布局标签 包括页眉 导航和页脚 由于某种原因 在我的打印样式表中显示 无 这些标签上的声明在 IE8 中被忽略 我只能假设后续的较低版本 我首先认为 IE9
  • php 的问题:读取文件名,生成 javascript 和 html

    UPDATE 再一次问好 我发现自己遇到了一个新问题 php代码在我的PC wamp服务器 上完美运行 但我现在已将其上传到免费的网络主机服务器上 虽然php部分运行完美 它生成数组 但javascript函数本身不起作用 因为没有照片在网
  • 如何在文本文件中找到最长的 N 行并将其打印到标准输出?

    第一行包含数字 N 的值 后跟多行 我可以按照n 2算法的顺序解决它 有人可以建议一个更好的吗 您可以使用最小堆并在 O n log N 中完成 heap new Min Heap N foreach line in text if len
  • 删除 PHP 中的标头

    为了允许缓存 PHP 生成的文件 我想确保 Pragma no cache 标头是not放 但是 如何删除可能已经设置的标头 这就对了could有可能 有人在代码中的某个地方写了header Pragma no cache 现在我想确保标头
  • PHP:删除任何扩展名的文件?

    当用户上传照片时 它会检查他们是否已经拥有一张照片 如果他们这样做 我希望它删除旧的 可以有任何扩展名 然后放入新的 有没有办法在不从数据库获取旧扩展的情况下做到这一点 目前的代码 del members gt prepare insert
  • 打开文件对象的大小

    有没有办法找到当前打开的文件对象的大小 具体来说 我正在使用 tarfile 模块来创建 tarfile 但我不希望 tarfile 超过特定大小 据我所知 tarfile 对象是类似文件的对象 所以我想通用的解决方案会起作用 ls la
  • 打开 PDF 或文件夹

    我尝试打开在 Flash Player 中运行的 swf 应用程序中通过鼠标单击触发的 PDF 或文件夹 在查找器 资源管理器中 通过 urlRequest 打开 PDF 和navigateToUrl 总是打开浏览器 我读到this htt
  • File.Delete 进程无法访问该文件,因为该文件正在被另一个进程使用

    public bool DownloadMp3File DownloadedMp3 mp3 WebClient client new WebClient string filePath bool wasDownload false try
  • 如何在会话自动加载的同时在 vim 中打开文件?

    我在 vimrc 中有以下代码 可以在 vim 启动时自动保存 加载会话 Session saving Automatically save rewrite the session when leaving Vim augroup leav
  • 从绝对路径获取名称,从最后一个斜杠获取子字符串,java android

    我想提取绝对路径的名称 如果我有一个值为 mnt sdcard Videos Videoname 的字符串 我想保存一个值为 Videoname 的字符串 字符串正在变化 我之前无法获取斜杠的数量 如何从最后一个斜杠中分割子字符串 mnt
  • 从 Java 访问文件名中带有空格的文件

    我想从java程序访问文件名中有空格的目录中的文件 但它不访问文件 场景是我在文件中有文件名 iread 从该文件中读取文件名 但无法在 java 中打开带有空格的文件 我们使用 File exist 函数来检查文件是否存在 但它返回 fa
  • Python下载器

    所以我试图编写一个脚本来使用 python 下载图片文件 我使用谷歌找到了这个 def 但是我下载的每张图片都 损坏 了 有任何想法吗 def download url Copy the contents of a file from a
  • PHP is_file 和服务器根相对路径

    请问如何使用 is file 和 folder file jpg 这样的路径 谢谢你 如果路径以 开头 则表示该路径是绝对路径 当路径是相对路径时 即不以 开头 则采用相对于 php 脚本的路径 如果您希望 folder file jpg
  • 在文件中查找一行并将其删除

    我正在寻找一个小代码片段 它将在文件中找到一行并删除该行 不是内容而是行 但找不到 例如 我在以下文件中 我的文件 txt aaa bbb ccc ddd 需要有这样的功能 public void removeLine String lin
  • 使大型静态数据文件可供 kubernetes pod 使用

    我有一些相当大的 UTF 8 数据文件 pod 需要在启动时加载到内存中 从几百 KB 到大约 50 MB 该项目 包括 helm 图表 是开源的 但其中一些文件不是开源的 否则我可能只会将它们包含在图像中 我最初的想法是创建配置映射 但我
  • 向每个表格单元格添加进度条以显示文件进度 - Java

    当您单击 加密 时 应用程序会对放入表中的每个文件进行加密 我想显示文件加密时的进度 然后 状态 列将从 未处理 更改为 已处理 类似于您查看电子邮件中附加的多个文件的方式 我一直在研究单元格渲染器和 ProgressBarTablecel
  • 读取一个文本文件,替换其中的单词,输出到另一个文本文件

    所以我试图在 GO 中编写一个程序来获取一个充满代码的文本文件并将其转换为 GO 代码 然后将该文件保存到 GO 文件或文本文件中 我一直在试图弄清楚如何保存对文本文件所做的更改 但我可以看到更改的唯一方法是通过 println 语句 因为
  • python 和回文

    我最近写了一个循环的方法 usr share dict words并使用我的返回回文列表ispalindrome x 方法 这是一些代码 有什么问题吗 它只会停止 10 分钟 然后返回文件中所有单词的列表 def reverse a ret

随机推荐

  • 会议通知

    全国高校Python数据分析与实训课程 高级研修班 通 知 各高校教务处 各相关院系负责人 依据 教育部高等学校教学指导委员会章程 规定 教育部高等学校教学指导委员会的任务之一是 组织师资培训 沟通信息 交流教学建设和教学改革经验 宣传推广
  • 2022 Java面试题

    Java面向对象有哪些特征 如何应用 面向对象编程是利用类和对象编程的一种思想 万物可归类 类是对于世界事物的高度抽象 不同的事物之间有不同的关系 一个类自身与外界的封装关系 一个父类和子类的继承关系 一个类和多个类的多态关系 万物皆对象
  • 基于MATLAB GUI的LSB语音信号数字水印

    基于MATLAB GUI的LSB语音信号数字水印 数字水印是一种在数字媒体中嵌入信息的技术 它可以用于版权保护 身份验证以及数据完整性验证等应用 在本文中 我们将介绍如何使用MATLAB GUI和最低有效位 Least Significan
  • Vue2.0知识点

    Vue2 0指令 v text指令 内容渲染指令 它会覆盖元素内部原有的内容 语法 插值表达式 专门用来解决v text会覆盖默认文本内容的问题 v text和插值表达式只能渲染纯文本内容 插值表达式不能用到属性节点 v html指令 可以
  • FFmpeg H264增加SEI

    先看使用场景 https blog csdn net lsheevyfg article details 80951415 https www jianshu com p 4d9120dfcd69 参考文章 https blog csdn
  • 【Python基础】Jupyter Notebook最常用的五大配置技巧

    说到Jupyter Notebook 以下简称Jupyter 想必很多人都不陌生 这是一款神奇的web应用 权且可以把它当作python超级笔记本 当然它还支持R Julia Scala Js等几十种语言 在Jupyter上 可以使用pyt
  • Spring Security OAuth2.0(四)-----OAuth2+JWT

    传统的通过 session 来记录用户认证信息的方式我们可以理解为这是一种有状态登录 而 JWT 则代表了一种无状态登录 无状态登录天然的具备单点登录能力 1 无状态登录 1 1 什么是有状态 有状态服务 即服务端需要记录每次会话的客户端信
  • Python中__str__的用法

    str 和 repr 如果要把一个类的实例变成 str 就需要实现特殊方法 str 不使用 str print打印出来是个对象 使用了就把对象变成字符串 class Person object def init self name gend
  • 蓝桥杯模块练习6-AD

    main c include
  • ag-grid Column API(机器翻译)

    Column API 一些API方法采用colKey类型为的列关键字 名为 Column string 这意味着您可以传递一个Column对象 通过调用其他方法之一接收到的对象 也可以传递Column ID 即string 列ID是列定义的
  • 【毕业设计】深度学习卫星遥感图像检测与识别系统(目标检测)

    文章目录 0 前言 1 课题背景 2 实现效果 3 Yolov5算法 4 数据处理和训练 5 最后 0 前言 Hi 大家好 这里是丹成学长的毕设系列文章 对毕设有任何疑问都可以问学长哦 这两年开始 各个学校对毕设的要求越来越高 难度也越来越
  • 远程控制,从个人便捷走向企业安全

    根据风险基础安全 Risk Based Security 的数据显示 2020年全球数据泄漏达到360亿条 创历史新高 对比传统的网络安全威胁 数据安全威胁更加多样化 80 的安全风险来自于内部人员或合作伙伴 威胁形式也更集中在账号体系薄弱
  • mybatis中association和collection的column传入多个参数问题

    mybatis中association和collection的column传入多个参数值 项目中在使用association和collection实现一对一和一对多关系时需要对关系中结果集进行筛选 如果使用懒加载模式 即联合使用select
  • mysql mariadb不能启动原因_centOS7 (64) MariaDB无法启动 跪求解决方法

    在CentOS7中mysql被 MariaDB所代替 幸得 贵在坚持 提点 顺利下载 MariaDB等相关软件但是安装完毕后 mariadb还是无法正常启动 root localhost service mariadb start Redi
  • mysql怎么替换部分字符串

    mysql替换部分字符串的方法 1 使用REPLACE 函数 语法 REPLACE 字符串 查找值 替换值 2 使用INSERT 函数 语法 INSERT 字符串 替换开始位置 要替换的字符数 替换值 mysql替换部分字符串 1 使用RE
  • 多租户mysql架构_团队开发框架实战—多租户架构

    1 对多租户的理解 多租户定义 多租户技术或称多重租赁技术 简称SaaS 是一种软件架构技术 是实现如何在多用户环境下 此处的多用户一般是面向企业用户 共用相同的系统或程序组件 并且可确保各用户间数据的隔离性 简单讲 在一台服务器上运行单个
  • XSS 跨站脚本

    XSS 跨站脚本 一 什么是XSS XSS Cross site Scripting 中文名跨站脚本攻击 其原理是攻击者利用浏览器执行前端代码 HTML CSS JavaScript 的特性 将恶意的JavaScript代码插入到页面中 当
  • LVGL动态图GIF实现 v7 version

    lvglv8 1以上的版本自带动态图库 github网址 LVGL GitHub 主要包含四个文件 gifdec c gifdec h lv gif c lvgif h 目录 lvgl release v8 1 lvgl release v
  • Cortex-AX系列性能对比

    首先要明确一个概念 Cortex并不是一种架构 而是ARM的一个系列 Cortex A系列 而我们通常意义的ARM7 ARM9 ARM11才是所谓的架构 同时需注意 Cortex A5 Cortex A8 Cortex A9 Cortex
  • ELF文件格式

    在介绍ELF格式之前 先简单说明一下可执行文件的生成流程 1 编写C源文件 或汇编源文件 2 准备共享库格式的目标文件 shared object file 如数学库 标准库 2 用编译器 compiler 将C编译成可重定位格式的目标文件