ELF全称:可执行链接格式,是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的。ELF文件有三种不同类型:

  1. 可重定位文件:包含代码和数据,用于链接成可执行文件或共享目标文件后使用(.o文件和.a静态库)。
  2. 可执行文件:包含二进制代码和数据,可直接复制到存储器并执行(/bin或/usr/bin目录下的文件。
  3. 共享目标文件:特殊的可重定位文件,可在加载或运行时被动态地加载到存储器并链接。

文件最前部为ELF文件头,描述了整个文件的基本属性,如文件类型,版本,目标机器类型,程序入口地址等,然后是各段,每段由段表描述。链接视图和执行视图下,段分别由Section Header Table和Program Header Table描述。

ELF头文件

由/usr/include/elf.h文件给出定义

typedef struct elf64_hdr {unsigned char  e_ident[EI_NIDENT];  //魔数 7F+’E’+’L’+’F’Elf64_Half e_type;                //文件类型 Elf64_Half e_machine;                //机器类型Elf64_Word e_version;                 //文件版本Elf64_Addr e_entry;               //进程开始的虚地址,即系统将控制转移的位置Elf64_Off e_phoff;                 //program header table的文件偏移Elf64_Off e_shoff;               //section header表的文件偏移Elf64_Word e_flags;               //处理器相关的标志Elf64_Half e_ehsize;              //ELF文件头的长度Elf64_Half e_phentsize;          //program header表中的入口的长度Elf64_Half e_phnum;                 //program header表中的入口数目Elf64_Half e_shentsize;          //section header表中的入口的长度Elf64_Half e_shnum;                 //section header表中的入口数目Elf64_Half e_shstrndx;           //section名表的位置,指出在section header表中的索引
} Elf64_Ehdr;

Program Header

目标文件或者共享文件的program header table描述了系统执行一个程序所需要的段或者其它信息。目标文件的一个段(segment)包含一个或者多个section。Program header只对可执行文件和共享目标文件有意义,对于程序的链接没有任何意义

typedef struct elf64_phdr {Elf64_Word p_type;        //段的类型Elf64_Word p_flags;       //段标志Elf64_Off p_offset;        //段偏移Elf64_Addr p_vaddr;        //段虚地址Elf64_Addr p_paddr;       //段物理地址Elf64_Xword p_filesz;        //段大小Elf64_Xword p_memsz;       //段在内存的占用Elf64_Xword p_align;       //段对齐
} Elf64_Phdr;

Section Header

文件的section header table可以定位所有的section

typedef struct elf64_shdr {Elf64_Word sh_name;       //段名,值为符号表索引Elf64_Word sh_type;      //类别Elf64_Xword sh_flags;       //程执行时的特性Elf64_Addr sh_addr;        //进程的内存映像中出现,则给出开始的虚地址Elf64_Off sh_offset;       //偏移Elf64_Xword sh_size;        //大小Elf64_Word sh_link;     //相对其他段的索引Elf64_Word sh_info;       //信息Elf64_Xword sh_addralign;   //对齐Elf64_Xword sh_entsize; //
} Elf64_Shdr;

Symbol Table

文件的符号表包含定位或重定位程序符号定义和引用时所需要的信息

typedef struct elf64_sym {Elf64_Word st_name;        //符号名unsigned char  st_info;    //符号类型unsigned char st_other;   //其他Elf64_Half st_shndx;        //段索引Elf64_Addr st_value;       //符号地址值Elf64_Xword st_size;     //符号大小
} Elf64_Sym;

ELF文件分析

为了分析elf文件,新建hello.c文件

#include <stdio.h>int add(void) {int a = 3;int b = 2;int c = a+b;return c;
}int main() {printf("%d\n",add());return 0;
}

新建MakeFile文件

hello: hello.ogcc -o hello hello.o
hello.o: hello.cgcc -c -o hello.o hello.c

执行make hello 后生成名为hello的elf可执行文件, 接着执行 readelf -h hello 输出头文件信息


从输出信息中可以得到魔数,机器架构,系统类型。可以看到文件大小为64bytes(0x40)执行hexdump -C hello 输出elf文件二进制信息,0x0 - 0x40 代表头结构数据范围

参考elf64_hdr结构定义我们可以读取到信息,比如7f 45 4c 56 ASCII码表示为 .ELF 。依次 02 01 01 00 分别表示64位对象,小端,文件头版本,其他。03 00 表示此文件为共享目标文件,等等。

执行 readelf -l hello 输出 Program header 信息


从先前表头hex读取到e_phnum = 0d 00 (小端转换00 0d)= (13) 即segment有13段,从Program header输出信息看到确实是13段。上图标注了第一段对应的hex编码范围。Section to Segment mapping 表示两种视图映射。

执行readelf -S hello 得到 Section Header 表

从先前的表头hex读取到 Section 数量e_shnum为 1f00 (小端转换001f) 代表有31个段

  1. 段起始偏移e_shoff为 98 39 00 00 00 00 00 00 (小端转换00 00 00 00 00 00 39 98)
  2. e_ehentsize为 40 00 (小端转换 00 40)
  3. 代码段编号16
    所以代码段地址为0x3998 + (0x40 * 0x10) = 0x3D98


现在来验证 sh_name, b9 00 00 00 (00 00 00 b9) 表示该段名称在.shstrtab中偏移量,
执行 readelf -x .shstrtab hello

在00 00 00 b9 处的编码确实是text。 现在来验证section在内存中的虚拟地址 执行 readelf -x .text hello 输出代码段信息


代码段虚拟地址sh_addr为60 10 00 00 等于由代码段输出得到的地址信息(0x00001060),由此上述关于代码段的计算是正确的。其他段的推导也是一样的。

Linux ELF文件相关推荐

  1. linux elf 文件理解与分析

    https://linux-audit.com/elf-binaries-on-linux-understanding-and-analysis/ 我们理所当然的使用一些工具.其中一部分就是 linu ...

  2. linux elf 文件查看工具 readelf

    Android在NDK开发工具中提供了readelf,用来帮助开发者查看编译后目标文件的组成结构和具体内容. 常用的有以下几个功能选项: 1)-h或者--file-header 显示在ELF文件头里包 ...

  3. Linux如何找到所有elf文件,linux – ELF文件中的导入表在哪里?

    But you can see in the attached picture,that on the offset 464 there are only zeros. 错误:上次我检查时,01,20 ...

  4. linux elf 文件加密

    ELF头的各个字段如下: #define EI_NIDENT 16 typedef struct{ unsigned char e_ident[EI_NIDENT]; //目标文件标识信息 Elf32 ...

  5. linux 导入函数,共享库 – Linux ELF文件:如何获取属于导入函数的共享对象

    How can I find out from which shared library/shared object the strcp function is obtained? 通常,您不能:该库 ...

  6. Linux ELF文件格式介绍

    文章目录 一.引言 二.介绍 三.ELF目标文件格式 3.1 常见段及对应用途 3.2 目标文件内容解析 3.2.1 代码段.text 3.2.2 只读数据段.rodata 3.2.3 数据段.dat ...

  7. linux无文件渗透执行elf

    01-简介 在进行Linux系统的攻击应急时,大家可能会查看pid以及/proc相关信息,比如通过/proc/$pid/cmdline查看某个可疑进程的启动命令,通过/proc/$pid/exe 抓样 ...

  8. IDA——动态调试Linux上的ELF文件(整合他人博客)

    先查看机器之间是否可以ping通 0x00:环境 待调试ELF文件 IDA 7.0 主机:Windows 虚拟机:Linux 达成效果:在Window上利用IDA远程动态调试linux里的ELF文件 ...

  9. linux elf 视频,linux 实例讲解elf文件

    elf是一种文件格式,用于存储linux程序,它内部有什么信息呢?大概包括编制好的计算机指令,数据,计算机在需要的时候把这个文件读取到内存中,cpu就可以从内存中一条一条的读取指令来执行.要想明白el ...

最新文章

  1. 已知子网掩码如何计算IP地址中的主机位
  2. HashTree(哈希树) ——和trie类似,只是将字符换成了质数,sphinx用到了???...
  3. ESD静电二极管,在汽车电子中的应用
  4. 若川的2016年度总结,毕业工作
  5. js 位运算符 ~, ,| ,^
  6. 【算法学习】堆排序(Heap Sorting)
  7. hdu 1425 sort用堆排序做的
  8. Android手机修改wifi图标,安卓手机怎么改wifi密码?
  9. excel数据透视表之交叉表分组
  10. 无源晶振(Crystal)的负载电容
  11. java poi 实现word文档分栏遇到的坑
  12. 切换输入法半角全角(打开关闭输入法)
  13. 利用感知机实现鸢尾花分类问题
  14. 一次新公司注册与小程序上线的历程
  15. svn update 出现skipped '.' 或skipped '目录名称'
  16. JAVA学习(四):Java流程控制语句(顺序结构、if条件语句、switch条件语句、循环语句与跳转语句)
  17. 字符串转化为json对象和json数组
  18. 字节数据要与0xFF相与
  19. 电视上设置禁止安装不是从Android,海信电视禁止安装第三方软件怎么办?当贝市场教你解决方法!...
  20. 医院信息系统 php,php医院门诊信息管理系统

热门文章

  1. Science综述:与时俱进的多主体仿真模型
  2. Xampp 删除与安装
  3. Core Dump核心转储
  4. 物理之物态变化---python最新程序编写
  5. BoundField中DataFormatString格式化数字,货币,日期
  6. 【内网安全】——CS操作指南(二)
  7. Windows 10 Build 14997中Edge浏览器已默认阻止Flash运行
  8. 【立创EDA】使用solidworks创建立创EDA 3D模型
  9. export default + export const
  10. Microsoft Edge 帮您淘 出现故障