ELF文件概述

一、简介

ELF 文件是一种用于存储可执行程序、目标文件、共享库等的标准文件格式,在 Linux 及其他类 Linux 操作系统(如 Unix 等)中广泛应用。它定义了一种规范的结构,使得操作系统能够准确地加载程序并使其在内存中正确执行。

简单来说,当我们编写一段代码(比如用 C 语言编写)并经过编译后,生成的可执行文件往往就是以 ELF 格式存在的。它包含了程序的代码段(存放可执行的机器指令)、数据段(存放程序中定义的各种变量等数据)、符号表(记录程序中定义的函数、变量等符号信息,用于链接等操作)等重要部分。

什么是可执行文件:

广义:文件中的数据是可执行代码的文件,例如:.out   .exe   .py   .sh

狭义:文件中的数据是机器码的文件,例如:.out   .exe   .dll   .so

可执行文件分类

Windows:PE    可执行程序:.exe    动态链接库:.dll    静态链接库:.lib

Linux:ELF    可执行程序:.out    动态链接库:.so    静态链接库:.a

文件格式

ELF(Executable and Linkable Format)是一种常见的可执行文件和共享库格式,其结构如下:

ELF header:

包含了 ELF 文件的基本属性信息。

头部(Header):ELF文件的头部包含了整个文件的基本信息,如文件类型、机器架构、入口点地址等。可以将头部看作是文件的元数据,就像书的封面上包含了书的基本信息。

 可以用readelf查看,命令如下

readelf -h

16字节ELF标识,前4字节是ELF文件标识"\x7fELF",不可修改

size of this header 即ELF文件头本身的大小,这里是 ELF文件头是64个字节

start of program headers 即程序表 segment在文件中的偏移,即56个字节

size of section headers 即段表section在文件中的偏移,即第64个字节

Number of program headers 即程序表的个数,为36个,说明这个文件中有36个程序表

Program header table:

描述了程序在内存中的加载情况,包括可执行代码段、数据段等。

Section header table:

描述了 ELF 文件中所有节区的信息,如代码节区、数据节区等。
节区数据:包含了 ELF 文件中的实际数据,如代码、数据等。
ELF 文件的结构可以根据不同的操作系统和体系结构而有所差异。
节区表(Section Table):节区表是一个数据结构,它描述了ELF文件中各个节区的位置和属性。类似于书的目录,它告诉你在书中的哪个位置可以找到某个章节或内容。
代码节区(Code Section):代码节区包含了程序的实际指令,即可执行的机器码。这部分就像是一本书中的具体章节内容,包含了实际的文字和故事情节。
数据节区(Data Section):数据节区存储了程序中使用的全局变量、静态变量和常量等数据。可以把它看作是书中的附录或者注释部分,包含了与故事情节相关的补充信息。
符号表(Symbol Table):符号表包含了程序中定义的函数和变量的信息,比如名称、地址等。可以将符号表类比为书的索引,你可以通过索引查找到书中特定关键字或人物的出现位置。
动态链接表(Dynamic Linking Table):动态链接表包含了程序在运行时所需的动态链接信息,比如依赖的共享库和符号解析的过程。它就像是一本参考书,提供了额外的信息和解释。

可以用readelf查看,命令如下

readelf -S


段的类型(sh_type):标识这个段的类型,例如:NULL(代表 无效段),  PROGBITS(存储了程序的数据和代码),SYMTAB(代表 符号表),STRTAB(代表 字符串表),RELA(代表 重定位表),HASH(符号表的hash表),DYNAMIC(代表 动态链接信息),NOBITS(代表 程序空间内没有数据),REL(重定位信息),DNYSYM(动态链接的符号表)。

段的地址(address): 表示执行时候的虚拟地址,这估计在程序装载的时候才有,待学习。

段的偏移(sh_offset)和段的大小(sh_size):表示该段相对于文件的偏移量和该段的存储大小,这里以十六进制体现

段的ES(sh_entsize):  表示该段如果存在一个表table,那么这个ES属性则显示每个entry的字节的大小,否则为0。

段的标志位(sh_flags):  表示该段在进程虚拟地址空间的属性,比如是否可写、要分配空间、可执行等。

二、ELF文件在IDA中展现形式

ELF文件本身是一个二进制文件,对应IDA中 HEX VIEW 界面中内容,但关注更多的内容可能是 IDA VIEW。IDA VIEW中是对 HEX VIEW 界面中内容从头到尾的解析,并且内容一一对应(HEX VIEW内容偏移和IDA VIEW的左侧地址对应,不管鼠标在IDA VIEW还是HEX VIEW的哪个位置停留,点击进另一个界面时,地址或偏移都是对应的)。不管二进制文件有多大,解析的汇编内容都只是在IDA VIEW,只是文件很大时,解析会比较慢。

如果二进制内容是文件头或节头或程序头,IDA VIEW中会以从LOAD段解析ELF文件,或是字符串或是顺序排列形式呈现,直到.plt节或.text节,IDA VIEW中开始以汇编代码的形式呈现。

IDA解析ELF格式时,会同时参考节头表和程序头(段)表。如果将节头表内容抹除或改偏移让IDA解析不到节表时,IDA VIEW会完全根据LOAD段来解析内容,原先现实的节全部变成LOAD。如果将程序头表内容抹除或改偏移让IDA解析不到程序头表时,IDA VIEW只会解析节表的内容,正常情况下的LOAD段那一部分内容不会在IDA VIEW和HEX VIEW中出现。

1.节表含义

1>节表名称信息

IDA没有展示elf文件所有节的内容,在IDA中使用Ctrl + s可显示节表名称等信息

全部的节表在上面已经展示过了,就不说了

2>节对应功能

.text: 该节中包含程序的指令代码;
.init: 该节包含进程初始化时要执行的程序指令;当程序开始运行时,系统会在进程进入主函数之前先执行这一个节中的指令代码;
.fini: 该节中包含进程终止时要执行的指令代码;当程序退出时,系统会执行这个节中的指令代码;
.bss : 该节中包含目标文件中未初始化的全局变量;一般情况下,可执行程序在开始执行时,系统会把这一段内容清零;但是在运行期间的.bss段是由系统动态初始化而成的,目标文件中的.bss节中并不包含任何内容,其长度为0,所以它的节类型为SHT_NOBITS;
.data:这两个节用于存放程序中已被初始化过的全局变量;在目标文件中,它们是要占用实际的存储空间的,这一点与.bss节不同;如果全局变量是整形                                                                    .rodata:这两个节中包含程序中的只读数据,例如函数体内,只读的字符串会存储在该节中;
.dynamic: 该节中包含动态链接信息,并且可能有SHF_ALLOC和SHF_WRITE等属性;
.dynstr : 该节中包含用于动态链接的字符串,一般是那些与符号表相关的动态符号的名字;
.dynsym : 该节中包含动态链接符号表;
.got : 该节中包含全局偏移表(global offset table),存放的是类似相对_GLOBAL_OFFSET_TABLE_的偏移;
.plt : 该节中包含函数链接表(program link table);
.hash : 该节中包含一张哈希表,用于动态段中查找动态符号;
.interp : 该节中包含ELF文件解析器的路径名;如果该节被包含在某个可装载的段中,那么该节的属性中应设置SHF_ALLOC标志位;
.strtab : 该节用于存放字符串,主要是那些符号表项的名字;如果一个目标文件中有一个可装载的段,并且其中含有符号表,则该节的属性中应该有SHF_ALLOC属性;
.symtab : 该节用于存放符号表;如果一个目标文件中有一个可装载的段,并且其中含有符号表,则该节的属性中应该有SHF_ALLOC属性;
.shstrtab: 该节是节名字表,含有所有其它节的名字;
.comment: 该节中包含版本控制信息;
.line : 该节中包含调试信息,包括哪些调试符号的行号,为程序指令码与源文件的行号建立联系;
.note : 该节中包含注释;
rel.dyn节的每个表项对应了除了外部过程调用的符号以外的所有重定位对象,
.rel.plt节的每个表项对应了所有外部过程调用符号的重定位信息。

三、步骤

1.查看 ELF 文件基本信息

使用file命令可以快速查看一个文件是否为 ELF 文件以及它的一些基本类型信息。例如,如果有一个名为pwn4的文件,在终端中执行

file pwn4

2.查看 ELF 文件详细结构(使用readelf工具)

安装readelf工具(在大多数 Linux 发行版中,它通常已经预装,如果没有,可以通过包管理器安装)。

1>要查看 ELF 文件的头部信息,可以执行:

readelf -h pwn4

这将显示 ELF 文件的头部结构,包括文件类型、目标机器架构、入口点地址等重要信息

2>要查看节区头表信息,可以执行:

readelf -S pwn4

这将显示各个节区的名称、大小、偏移量等详细信息

3>要查看程序头表信息,可以执行:

readelf -l pwn4

这将显示各个段在内存中的映射情况等信息

3.分析 ELF 文件中的符号表(使用nm工具)

安装nm工具(同样,在大多数 Linux 发行版中通常已预装)。

执行以下命令来分析符号表:

nm pwn4

这将显示出文件中所有的符号(包括函数、变量等)及其地址等信息,有助于了解程序内部的结构和函数调用关系

四、IDA使用简记

1.快捷键

F5:查看伪代码

D:Options——Setup Data Types便可选定D时设置的数据类型;

A:可以将图形字符由十六进制数转化成图形,如果一个字节不行,可多选一些字节;

C:将数据转换成代码;

G:跳转至相应的地址处;

Ctrl+F:寻找相应名称的内容;

Shift+F9:打开结构体类型窗口;

在结构体类型窗口中,

Insert(Fn+PgDn得到):创建新的结构体类型;

Delete:删除某一个结构体类型;

在结构体end处,按‘D’便可插入成员变量;

Alt+Q将某个变量转成一个结构体类型,如果代码区有符号变红,说明该地址处原先的也是一个构体,但后来被其它的定义给覆盖,按两下‘K’即可打散数据;

K:打散数据;

T:将某一符号转成结构体成员变量;

对于一个函数起始处,D、C、右键——CreateFunction即可还原。

2.ida中查找数组类型及个数的方法

通过Edit——Operand——Number——选择转换的类型。

Y键可以让变量的类型重新更改;

写一个*.h文件,然后通过File——LoadFile——Parse C Header File (Ctrl+ F9),然后选择插入结构体,用快捷键INS,会出现一个

窗口界面,左下角出现Add standard Structcture,点击便可从导入的结构体中选取。很多时候如果ida不能识别某些结构体,可以写写头文件,然后导入到ida中。

在汇编中,只要是符合内容属性一致、地址具有连续性,就可以断定这一串数据是数组了,当然可能作者并没有定义数组,但是只要符合以上两个属性,就是了。数据的类型首先是判断字节数,然后根据指令,判断是浮点型数据,还是整型数据,当然通过普通整型赋值指令也可以判别。lea edi, [esp+esi4+1D0h+var_1A4]指令便说明var_1A4为某一数组的首地址,每个元素字节为4,因为比例因子为4,lea edx, [esp+eax8+1D0h+var_168]指令中var_168是元素字节为8的数组的首地址。

对于数组元素,一般都会有赋值,所以可通过赋值,在内存查找相似数据且相连的一个数据,其中的个数便是数组元素个数。当然对于占很大字节的数组初始化为0内容时,一般会用串拷贝指令,且是rep stosd,如指令mov ecx, 58h xor eax, eax lea edi, [esp+1D0h+var_160] mov [esp+1D0h+var_168], 0 mov [esp+1D0h+var_164], 0 xor ebp, ebp rep stosd

### Vivado 中 ELF 文件的作用解释 #### ELF 文件概述 可执行链接格式 (Executable and Linkable Format, ELF) 是一种用于二进制文件的标准文件格式,广泛应用于 Unix 和类 Unix 系统中。在 Xilinx Vivado 工具链环境中,ELF 文件主要用于存储微处理器或软核(如 MicroBlaze 或 Zynq PS 部分中的 ARM 处理器)程序的机器码及其相关数据[^1]。 #### ELF 文件的主要用途 - **调试与仿真** 在开发过程中,工程师可以利用 ELF 文件来进行硬件平台上的软件调试以及功能验证。通过工具菜单 `Tool → Associate Elf file` 可以加载指定的应用程序到目标设备上并启动调试会话。 - **配置引导加载程序** 对于嵌入式系统而言,通常需要一个初始阶段来设置内存映射、初始化外设等操作;这些工作往往由专门设计好的引导代码完成。而该部分逻辑同样会被编译成 ELF 形式的镜像以便后续处理[^3]。 - **生成其他类型的固件映像** 当应用程序编写完毕并通过测试之后,可能还需要将其转换为目标板所能识别的形式——比如 SREC 文本记录格式。此时可以通过特定命令如 `mb-O srec my_app.elf my_app.srec` 来实现这种转变过程[^4]。 - **配合比特流共同部署至 FPGA 上** 如果项目涉及到将定制化的 IP 核同预定义好结构框架相结合,则最终产出既包含了硬件描述也涵盖了运行在其之上的应用层指令集架构的信息包体。这时就需要借助某些手段使得二者能够协同运作起来,例如采用关联机制让两者之间建立联系[^2]。 综上所述,在基于 Xilinx 平台开展的设计活动中,正确理解和运用 ELF 文件对于提高工作效率有着重要意义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值