elf文件解析【一】

  • Post author:
  • Post category:其他


记录学习的过程,好记性不如烂笔头———20221003


程序编译与链接



特点:

  • 不是“一步到位”“一气呵成”,而是环环相扣
  • 分为

    预编译、编译、汇编、链接

    阶段
  • 每个阶段调用不同的工具去完成
  • 上一编译阶段的输出作为下一编译阶段的输入



过程:


  • 预处理:

    源文件.c ->处理后的源文件.i

  • 编译:

    源文件.i->汇编文件.s

  • 汇编:

    汇编文件.s->目标文件.o

  • 链接:

    可重定位的目标文件.o->可执行目标文件(elf)



思考:

为什么不直接生成可执行文件?

  • gnu的思想,一个工具只干一件事
  • 计算机工业思维:标准接口+分层


    • 简化编译器的工作,提高复用性

    • 适配更多的平台、cpu架构、指令集



目标文件类型:

  • 可重定位目标文件(relocatable files),编译生成的文件,可被链接成可执行文件


    eg: linux下 .o 文件

  • 可执行目标文件(executable files),可以直接执行的程序,典型的ELF文件格式


    eg: linux 下的/bin/bash文件

  • 可被共享目标文件(shared object file),动态链接文件,可以和其他的可重定位文件和共享目标文件一起链接,生成新的目标文件


    eg: linux下的 .so 文件


  • 核心转存文件(core dump file),进程信息存储文件,当进程意外终止时,系统将该进程的地址空间以及终止时的一些信息存储到该文件



    eg: liunx下的 core dump 文件


注:

gcc 新版本的默认配置会导致编译后直接就是共享目标文件,需要谈到PIE(position-independent-executable),这是linux程序的一种保护机制,是gcc 的一个功能选项,目的是为了让程序在任意地址装载,减少系统攻击风险,如果需要生成 executable file 直接在编译的时候加上-no-pie参数即可

可执行文件结构



文件构成:

  • 由 section 组成,由 section header table 描述的一系列 section 集合
  • 查看节头表

    $ readelf -S main.o
  • .text 可执行指令代码
  • .data 初始化的全局变量和静态局部变量
  • .bss 未初始化的全局变量
  • .rodata 字符串、常量及printf打印的字符串常量等



描述信息:


  • ELF header 描述文件类型,运行的处理器平台等信息
  • program header table 描述一个文件中有哪些段 segment,一个段通常由几个section组成,段是加载器使用的
  • section header table 描述文件中有哪些 section,section 是给链接器使用的
  • .strtab 字符串表,存放函数名,变量名,用于调试、反汇编
  • .symtab 符号表,存放符号地址等



例子分析:








readelf -h main.o 查看 ELF header 【可重定位目标文件】







readelf -S main.o 查看 section 【可重定位目标文件】



readelf -h a.out 查看 ELF header 【可执行文件】



readelf -S a.out 查看 section 【可执行文件】



readelf -h libmath.a 查看 ELF header



readelf -h libmath.so 查看 ELF header  【可被共享目标文件】



版权声明:本文为weixin_40862294原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。