目录

  • 前言
  • elf文件格式
    • 1、大致结构
    • 2、ELF header(Ehdr)
    • 3、Program Header Table(Phdr)
    • 4、section header table(Shdr)
  • 查看elf文件信息

前言

elf文件是储存linux下可重定位文件(.o,.ko),可执行文件,共享目标文件(.so)的一种文件。


elf文件格式

1、大致结构

2、ELF header(Ehdr)
  • ELF header的定义可以在 /usr/include/elf.h 中找到。Elf32_Ehdr是32位 ELF header的结构体。Elf64_Ehdr是64位ELF header的结构体,两者主要区别在于某些成员的长度不一样;

  • Ehdr 各个成员的说明

    e_ident[**]     //elf标识
    e_type;         //elf类型(重定位文件rel(.o,.ko),可执行文件,共享目标文件dyn(.so))
    e_ machine;     //目标文件体系类型,即运行架构,如x86、riscv、arm等
    e_version;      //目标文件版本
    e_entry;        //elf入口地址
    e_ phoff;       //程序头部偏移
    e_shoff;        //节区头部偏移
    e_flags;        //处理器的特定标志,32位和64位Intel架构都没有定义标志,因此eflags的值是0
    e_ehsize;       //ELF格式头部大小
    e_phentsize;    //程序头部表项大小
    e_phnum;        //程序头表项个数,即segment数(各个segment连续存放)
    e_shentsize;    //节区头部表项大小
    e_shnum;        //节区表项个数,即section数(各个section连续存放)
    e_shstrndx;     //str节区(symbol的名字)在节区中位置(inedx)//可以使用命令 readelf 文件名,帮助理解
    

    ELF header(Ehdr)
    ELF文件解析(二):ELF header详解 - JollyWing - 博客园 (cnblogs.com)

3、Program Header Table(Phdr)
  • 将多个section 再包一层,各个成员说明

    p_type;         //segment类型,segment就是一些段信息(.text,.rodata..),//一个segment包含多个section
    p_offset;       //segment在文件中的偏移
    p_vaddr;        //segment虚地址
    p_paddr;        //物理地址
    p_filesz;       //文件中segment字节数
    p_memsz;        //内存中segment字节数
    p_flags;
    p_align;
    

注意:一般只有可执行文件才有(有错请指出)

4、section header table(Shdr)
  • section header结构体的定义可以在 /usr/include/elf.h

  • Shdr 各成员说明

    sh_name;           //一个索引值,在shstrtable(section header string table,包含section name的字符串表,也是一个section)中的索引
    sh_type;           //节区种类,如rel*
    sh_flags;          //可写,可分配,可执行等属性
    sh_addr;           //如果section会出现在进程的内存映像中,给出了section第一字节的虚拟地址;Relocatable file 的虚存地址都为0。Executable file 和 Shared object file 才会为有需要的 Section 计算虚存地址
    sh_offset;         //给出节区第一个字节在elf文件中的偏移
    sh_size;           //节区大小
    sh_link;           //给出字节头部表索引链接
    sh_info;           //给出节区附加信息
    sh_addralign;      //地址对齐约束
    sh_entsize;        //给出对于某些有固定项目的大小,如符号表,这个值给出了每个记录大小。//一个可执行文件中包含多个section段(对应源文件中使用section定义的段,链接脚本会定义哪些段为代码),一个section中有可能有多个函数(多段代码使用一个section定义)
    //可以使用命令 objdump -s -d 文件名,查看文件的的section信息,帮助理解
    
  • .symtab(符号表,section的一种),符号表中每个entry 的结构如下:

    st_name;        //一个索引值,在shstrtable(section header string table,包含section name的字符串表,也是一个section)中的索引
    st_value;       //可重定向文件(.ko):相对于节起始地址的偏移。//可执行文件(vmlinux):绝对地址。
    st_size;        //符号所指内容占据空间的大小(变量的大小,函数的大小)
    st_info;        //它的高4位表示 Symbol Binding,低4位表示 Symbol Type
    st_other;
    st_shndx;       //可重定向文件(.ko):对应节区的在节区组中的下标,和st_value组合使用
    
  • 重定位节(rela section)

  1. 为需要重新计算地址的地方提供定位信息
    一般体现为引用外部函数时,加载到内存时需要重新定位外部函数的地址
    .text 的重定位信息在 .rela_text, 以此类推

  2. 每个entry的结构;

    typedef struct
    {Elf64_Addr r_offset; /* 重定位文件 表示要重定位的地方,相对于对应节区的起始地址的相对地址;可执行文件 表示要重定位的地方的地址*/
    Elf64_Xword r_info; /* 低32位表示重定向的类型,高32位表示符号在符号表中的下标 */
    Elf64_Sxword r_addend;
    } Elf64_Rela# 计算公式:
    # R_386_64(1) result = S + A + r_addend(64位才有);
    # R_386_PC64(2) result = S - P + A + r_addend(64位才有);
    # result: 重定向后填入P指向位置的值,即替换result的值
    # P:要被重定位地方的地址偏移,即 r_offset + 相应节区的起始地址
    # A:要被重定位地方记录的数值
    # S:r_info找到的符号的地址,.o st_value + section_baseaddr, 可执行文件 st_value
    root:~$  readelf -x 20 ./crc32c-intel.koHex dump of section '__jump_table':NOTE: This section has relocations against it, but these have NOT been applied to this dump.0x00000000 00000000 00000000 00000000 00000000 ................0x00000010 00000000 00000000                   ........root:~$ readelf -x 21 ./crc32c-intel.koHex dump of section '.rela__jump_table':0x00000000 00000000 00000000 01000000 02000000 ................0x00000010 77030000 00000000 08000000 00000000 w...............0x00000020 01000000 02000000 7e030000 00000000 ........~.......0x00000030 10000000 00000000 01000000 d7000000 ................0x00000040 00000000 00000000                   ........root:~$ readelf -r ./crc32c-intel.ko
    ...
    Relocation section '.rela__jump_table' at offset 0x2bd8 contains 3 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000000000  000200000001 R_X86_64_64       0000000000000000 .text + 377
    000000000008  000200000001 R_X86_64_64       0000000000000000 .text + 37e
    000000000010  00d700000001 R_X86_64_64       0000000000000000 retp_enabled_key + 0
    ...
    
  3. 重定位的大致过程

    section header table(Shdr)
    ELF格式探析之三:sections - JollyWing - 博客园 (cnblogs.com)
    .symtab(符号表,section的一种)
    重定位信息
    (37条消息) Linux系统–ELF文件之可重定位文件(Relocatable file)解析_Barry-CSDN博客

  4. 理解例子



查看elf文件信息

readelf 依赖 binutils:http://ftp.gnu.org/gnu/binutils/

  • ELF header的信息:readelf -h

    jingl@JingL$ readelf -h ./crc32c-intel.ko
    ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              REL (Relocatable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x0Start of program headers:          0 (bytes into file)Start of section headers:          19784 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           0 (bytes)Number of program headers:         0Size of section headers:           64 (bytes)Number of section headers:         29Section header string table index: 28
    
  • program header信息: readelf -l

  • Section 信息:readelf -S

    jingl@JingL$ readelf -S ./crc32c-intel.ko
    There are 29 section headers, starting at offset 0x4d48:Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .note.gnu.build-i NOTE             0000000000000000  000000400000000000000024  0000000000000000   A       0     0     4
    ...[28] .shstrtab         STRTAB           0000000000000000  00004c200000000000000121  0000000000000000           0     0     1
    Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),l (large), p (processor specific)
    
  • 查看某一段的数据:readelf -x num

    jingl@JingL$ readelf -x 8 ./crc32c-intel.koHex dump of section '.altinstr_replacement':0x00000000 0faee8ff e7                         .....jingl@JingL$ readelf -x 11 ./crc32c-intel.koHex dump of section '.altinstructions':NOTE: This section has relocations against it, but these have NOT been applied to this dump.0x00000000 00000000 00000000 7d000200 00000000 ........}.......0x00000010 00000000 ed001105                   ........jingl@JingL$ readelf -x 12 ./crc32c-intel.koHex dump of section '.rela.altinstructions':0x00000000 00000000 00000000 02000000 03000000 ................0x00000010 41000000 00000000 0c000000 00000000 A...............0x00000020 02000000 02000000 7e030000 00000000 ........~.......0x00000030 10000000 00000000 02000000 05000000 ................0x00000040 00000000 00000000                   ........jingl@JingL$ readelf -x 20 ./crc32c-intel.koHex dump of section '__jump_table':NOTE: This section has relocations against it, but these have NOT been applied to this dump.0x00000000 00000000 00000000 00000000 00000000 ................0x00000010 00000000 00000000                   ........jingl@JingL$ readelf -x 21 ./crc32c-intel.koHex dump of section '.rela__jump_table':0x00000000 00000000 00000000 01000000 02000000 ................0x00000010 77030000 00000000 08000000 00000000 w...............0x00000020 01000000 02000000 7e030000 00000000 ........~.......0x00000030 10000000 00000000 01000000 d7000000 ................0x00000040 00000000 00000000                   ........
  • Symbol table 信息:readelf -s

    jingl@JingL$ readelf -s./crc32c-intel.koSymbol table '.symtab' contains 222 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1
    ...220: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND boot_cpu_data221: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __kernel_fpu_end
    
  • 重定位信息:readelf -r

    root:~$ readelf -r ./crc32c-intel.ko
    ...
    Relocation section '.rela__jump_table' at offset 0x2bd8 contains 3 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000000000  000200000001 R_X86_64_64       0000000000000000 .text + 377
    000000000008  000200000001 R_X86_64_64       0000000000000000 .text + 37e
    000000000010  00d700000001 R_X86_64_64       0000000000000000 retp_enabled_key + 0
    ...
    
  • 反汇编 代码段:objdum -d

  • 删除elf文件中的段:strip <option[s]> <in-file[s]>
    常用选项如下:

    -s --strip-allRemove all symbol and relocation information注: 删除其他符号表段和调试信息段,但不删除 .shstrtab 段-g -S -d --strip-debugRemove all debugging symbols & sections这几个选项的功能是一样,即移除上述5个".debug_"开头的调试信息段,仍会保留符号表--only-keep-debugStrip everything but the debug information注:段的总数量没有减少,但文件大小减少了;对比了"readelf -S"输出中的"offset"段,发现其中前面若干段的offset都没有变化,即size为0了。-R --remove-section=<name>Also remove section <name> from the output移除指定段,比如 strip --remove-section=.symtab a.outstrip --remove-section=.strtab a.out
    

    驱动文件(.ko)可能包含调试信息(.debug_info,依赖config中的CONFIG_DEBUG_INFO配置),可以使用strip --strip-debug ./xxx.ko去除;

    使用strip, eu-strip, objcopy等剥离与导回符号表及调试信息
    compile kernel with debug info

Linux elf文件分析相关推荐

  1. linux core文件的信息,linux core文件分析

    linux core文件分析 王钰琪 2017年3月2日 No Comment linux系统的core文件是进程崩溃时产生的快照信息,用于复现进程崩溃时的场景,是程序员分析进程崩溃原因的重要信息. ...

  2. Linux ELF文件

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

  3. linux elf 文件理解与分析

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

  4. linux ELF文件格式分析

    一.ELF文件格式概述 1. ELF:是一种对象文件的格式,用于定义不同类型的对象文件中都放了什么东西.以及都以什么样的格式去放这些东西. 二.分析一个ELF文件 以一个最简单的helloworld程 ...

  5. linux分析文件格式,linux elf文件格式分析

    #include void main() { printf("hello,jinxin!"); } 然后执行: gcc -o jin jin.c readelf -a jin EL ...

  6. linux elf 文件查看工具 readelf

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

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

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

  8. linux elf 文件加密

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

  9. linux wptmp文件分析,wordpress上传图片提示“缺少临时文件夹”的解决方法

    摘要:使用wordpress编辑器上传图片时出现了"缺少临时文件夹"的提示,该提示通常是由于服务器php配置的原因,如果之前上... 使用wordpress编辑器上传图片时出现了& ...

  10. linux根文件分析,Linux根文件系统详解

    文件系统: rootfs:#根文件系统 FHS:Linux /boot:#系统启动相关的文件,如内核.initrd,以及grub(bootloader) /dev:#设备文件 块设备:随机访问,数据块 ...

最新文章

  1. zabbix4.0使用snmp代理方式监控vcenter6.5
  2. HTTPS 证书配置
  3. 1930年的上海是什么样
  4. [并发编程] - Executor框架#ThreadPoolExecutor源码解读01
  5. 分布式与人工智能课程(part9)--Pandas绘图
  6. Silverlight 2 Beta 1版本缺陷列表
  7. 谈谈NLP下一个主战场:万亿参数的预训练模型!
  8. 关于Java交换两个对象的问题
  9. 京东资深架构师代码评审歪诗
  10. 如何查看windows某个目录下所有文件/文件夹的大小
  11. 【微信服务号开发】01.接入指南
  12. 【树状数组 思维题】luoguP3616 富金森林公园
  13. ztree 异步展开节点显示不出来_用户管理、角色管理、模块管理、zTree的使用
  14. 计算机快捷键屏幕录制,如何录制电脑屏幕视频-电脑实用快捷键(9页)-原创力文档...
  15. 直方图均衡化算法、直方图匹配算法 C++ 代码
  16. 海康存储硬盘盒开箱+小螃蟹RTL9210固件更新+量产软件下载
  17. 计算机游戏act指的是什么游戏,忍龙2领衔!5款史上最佳的ACT游戏推荐,值得一玩!...
  18. 揭秘AI创业江湖里的“师徒帮”:同门师兄弟搭档 导师坐镇后方
  19. 滚雪球学 Python 第二轮封笔之文,类函数、成员函数、静态函数、抽象函数、方法伪装属性
  20. Miracle密码算法开源库(十二)分析 :mrflsh3.c

热门文章

  1. 计算机中的各种字符编码
  2. 字体设计 css_设计好CSS字体堆栈的三个步骤
  3. matlab生成的图显示数据类型,matlab中数据类型及图像显示
  4. InstallShield 2020中文版
  5. 软件分析与设计习题集
  6. 计算机1级题库软件,计算机一级软件哪个好_计算机一级刷题软件_计算机一级试题软件...
  7. [php] laravel predis 使用 hscan 和 scan
  8. 工厂模式UML类图(Pizza为例)
  9. 什么是云计算管理平台
  10. dell网卡linux驱动,Dell R720上安装linux网卡驱动