前言:

  熟悉elf文件结构是一件很不错的事,因为安卓中的so加固以及修复都是需要这些知识的,包括pwn里面的rop之类的,也都是

和got节,plt节息息相关的,个人建议是在搞懂elf文件结构后,自己实现一个解析器,把注释写好,方便忘了再进一步重温,写的不好

见谅。

一. elf文件概述

elf文件包括了可执行文件,共享文件,目标文件这三类,其中安卓中涉及到的就是so文件,这个其实就是一个共享文件,类似

windows上的dll文件,目标文件是汇编文件,后缀为.o的文件,与可执行文件不同的是,并没有段头表,因为段是由相同功能的

节组合成的,而目标文件只是一个模块,并没有和其他模块进行链接,也就是节也没有合并,所以不存在段这个概念,程序的入口点

地址也是为空的,可执行文件和共享文件的话,大体结构和目标文件相同,多了段的概念,然后提供了两种视图(链接视图和装载视图)

二.elf文件结构

看起来其实不复杂,文件头,程序头表,节头表,节,段(其实就是相同功能节的组合体),接下来单独说说各个部分

三.elf文件头

这里搬出来010editor来看,这里是我导入之前做的crackme的so文件

好像名字奇奇怪怪的,我直接搬上,elf结构体定义

typedef struct

{

    unsigned char e_ident[EI_NIDENT];  /* Magic number and other info */

    Elf32_Half   e_type;         /* Object file type */

    Elf32_Half   e_machine;       /* Architecture */

    Elf32_Word   e_version;       /* Object file version */

    Elf32_Addr   e_entry;    /* Entry point virtual address */

    Elf32_Off   e_phoff;    /* Program header table file offset */

    Elf32_Off   e_shoff;    /* Section header table file offset */

    Elf32_Word   e_flags;    /* Processor-specific flags */

    Elf32_Half   e_ehsize;       /* ELF header size in bytes */

    Elf32_Half   e_phentsize;     /* Program header table entry size */

    Elf32_Half   e_phnum;    /* Program header table entry count */

    Elf32_Half   e_shentsize;     /* Section header table entry size */

    Elf32_Half   e_shnum;    /* Section header table entry count */

    Elf32_Half   e_shstrndx;      /* Section header string table index */

} Elf32_Ehdr;

重点说说几个字段,没说的说明比较简单易懂

1. e_ident:魔数,标识是哪个文件

2. e_phoff:程序头表在文件中的偏移

3. e_shoff: 程序节表在文件中的编译

4.e_phentsize: elf头占多少字节,32位的so,一般为52个字节

5. e_phnum: 程序头表中有关程序头的结构体个数,类似一个int数组,中int的个数

6. e_shnum:  和e_phnum差不多,把主语换成节头表

7. e_shstrndx: .strtab节在节头表的下标,因为里面存着所有节的名字

四.节头表解析

typedef struct
{
Elf32_Word sh_name; /* Section name (string tbl index) */
Elf32_Word sh_type; /* Section type */
Elf32_Word sh_flags; /* Section flags */
Elf32_Addr sh_addr; /* Section virtual addr at execution */
Elf32_Off sh_offset; /* Section file offset */
Elf32_Word sh_size; /* Section size in bytes */
Elf32_Word sh_link; /* Link to another section */
Elf32_Word sh_info; /* Additional section information */
Elf32_Word sh_addralign; /* Section alignment */
Elf32_Word sh_entsize; /* Entry size if section holds table */
} Elf32_Shdr;

节头表的结构如上图,实际上节头表就是上图结构体的数组,里面的数量是上面elf文件头中的e_shnum决定的,但是注意这个结构体并不是我们所想的节

也只是一个中间过渡的东西,只是定义了每个节在文件的哪个位置,名字叫什么,大小,类型是什么,具体的内容,还要根据其中定义好的偏移和大小再

去查找,接下来说说每个字段的含义

1.sh_name  是字符串节的下表,通常是先根据文件头中的strndx字段找到字符串节,然后再根据这个sh_name,找到节的名字

2. sh_type  表明这个节的类型是什么,内容比较多,直接上图

3.sh_flag 表明这个节是否可读可写可执行,记忆性的东西,直接上图

4.sh_addr  将会映射到虚拟内存空间中的地址

5.sh_size 和sh_off: 前一个是节的大小,后一个是节在文件中的偏移

在linux上也可以通过readelf -S xxx(文件名)进行查看

五. 特殊的节

五.1  .symtab

符号表的节,一般的so文件都会被抹去,怕被反编译,直接还原出符号名,也是一个结构体数组

st_name: 在字符串表中的下标

st_value :真正的值

st_size: 大小

st_info: 符号类别

毕竟符号分为局部符号,全局符号,还得标记是不是动态链接的

st_stndx: 符号属于哪个段,那个段在节头表的下标

挑了个so文件,发现里面的符号表已经被抹去了,-s只能查看.dynsym这个动态链接的节了

2..dynsym和.dynstr

动态链接符号表,里面主要存放着动态链接的符号,.dynstr里面主要存放动态链接符号的字符串名,

3. .rel.节名

重定位的表,很重要,因为这个表需要告诉linker哪个符号需要重定位

4. .plt节和.got节

出现.plt节的原因是有延迟绑定机制,因为动态链接中,符号很多,而且有些符号还没用到

那么重定位的负担就很重,所以就出现了延迟绑定,只有用到了该符号再进行绑定(这里的绑定主要说的是got表中填入符号的地址)

所以汇编代码大概是这样的:

jmp 后面的地址,是got表中的内容,但是如果没用过这个符号,里面填写的是push n的地址,也就是跳转到下一条指令了,

然后在把got表的下标和模块的id入栈,调用符号绑定的函数,实现延迟绑定,所以.plt节实际上就是一个got表的跳板,

六.程序头表(segment)
elf可分为两种视图,一种是链接视图,还有一种是装载视图

实际上不需要想的很复杂,段实际上就是相同功能的节的集合,本质上还是节,不过装载过程中所需的信息只和段有关,这也是为什么so加固中,可以去动节的一些信息,为我们解壳提供便利

typedef struct

{
  Elf32_Word    p_type;            /* Segment type */
  Elf32_Off    p_offset;          /* Segment file offset */
  Elf32_Addr    p_vaddr;        /* Segment virtual address */
  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;

也是一个结构体数组,注释也写得很清楚了。略

总结: 重心还是在节那块,参考了程序员自我修养,和看雪的几篇文章,但是看雪文章明显不如书有精华了,建议还是看看书

elf文件结构解读以及plt节got节的理解的更多相关文章

  1. ELF文件结构

    ELF文件结构 ELF文件的全称是Executable and Linkable Format,直译为"可执行可链接格式",包括目标文件(.o).可执行文件(可以直接运行).静态链 ...

  2. PE文件格式---节和节表

    17.1.4  节表和节 从排列位置来看,PE文件在DOS部分和PE文件头部分以后就是节表和多个不同的节(如图17.1中的③和④所示).要理解什么是节表,什么是节以及它们之间的关系,那就首先要了解Wi ...

  3. ELF文件结构描述

    ELF目标文件格式最前部ELF文件头(ELF Header),它包含了描述了整个文件的基本属性,比如ELF文件版本.目标机器型号.程序入口地址等.其中ELF文件与段有关的重要结构就是段表(Sectio ...

  4. elf文件中的.plt .rel.dyn .rel.plt .got .got.plt的关系

    .plt的作用是一个跳板,保存了某个符号在重定位表中的偏移量(用来第一次查找某个符号)和对应的.got.plt的对应的地址 .rel.dyn重定向表,在程序启动时就需要重定位完成. .rel.plt保 ...

  5. 程序运行之ELF文件结构

    ELF目标文件格式的最前部是ELF文件头.包含了整个文件的基本属性.比如ELF文件版本,目标机器型号,程序入口地址等.然后是ELF的各个段,其中ELF文件中与段有关的重要结构就是段表.段表描述了ELF ...

  6. 第一百二十九节,JavaScript,理解JavaScript库

    JavaScript,理解JavaScript库 学习要点: 1.项目介绍 2.理解JavaScript库 3.创建基础库 从本章,我们来用之前的基础知识来写一个项目,用以巩固之前所学.那么,每个项目 ...

  7. Vue-cli2.0 第3节 解读Vue-cli模板

    Vue-cli2.0 第3节 解读Vue-cli模板 目录 Vue-cli2.0 第3节 解读Vue-cli模板 第3节 解读Vue-cli模板 1. npm run build命令 2. main. ...

  8. Android C语言_init函数和constructor属性及.init/.init_array节探索

    本篇文章主要介绍了"Android C语言_init函数和constructor属性及.init/.init_array节探索",主要涉及到Android C语言_init函数和c ...

  9. Android so库文件的区节section修复代码分析

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78818917 一.Android so库文件的节表secion修复方案整理 1.简 ...

随机推荐

  1. 20192113 2020-2021-2 《Python程序设计》实验三报告

    20192113 2020-2021-2 <Python程序设计>实验三报告 课程:<Python程序设计> 班级: 1921 姓名: 衣丽莎 学号:20192113 实验教师 ...

  2. Scrum Master 生存指南

    近年来,出现了一批新兴且广受关注的岗位,以 Scrum Master 为典型代表.2018年,Scrum Master 的平均工资为98239美元.领英更是将其列为2019年最有前途的工作之一.但对于 ...

  3. LIN总线多从机与主机通信(控制+反馈)

    概念 首先要明确以下两点: LIN 总线通信方式为主从机通信,属于异步通信 "帧头 + 数据帧"才算一完整报文 设计方案 多从机与主机通信数据流(控制+反馈)如下: 一号从机: 第 ...

  4. 1. 回顾Servlet

    回顾Servlet 创建web工程 servlet-api:http://dwz.date/aTGa 编写Servlet import javax.servlet.ServletException; ...

  5. [论文阅读笔记] Unsupervised Attributed Network Embedding via Cross Fusion

    [论文阅读笔记] Unsupervised Attributed Network Embedding via Cross Fusion 本文结构 解决问题 主要贡献 算法原理 实验结果 参考文献 (1 ...

  6. 使用Apache TVM将机器学习编译为WASM和WebGPU

    使用Apache TVM将机器学习编译为WASM和WebGPU TLDR 在Apache TVM深度学习编译器中引入了对WASM和WebGPU的支持.实验表明,在将模型部署到Web时,TVM的WebG ...

  7. Paddle概述

    Paddle概述 本文结合深度学习理论与实践,使用百度飞桨平台实现自然语言处理.计算机视觉及个性化推荐等领域的经典应用. 实践部分使用飞桨深度学习开源框架,适配最新的2.0版本,默认使用动态图编程范式 ...

  8. Python 应用领域以及版本之间的区别

    Python 应用领域以及版本之间的区别 一.Python应用领域 1. Python+人工智能,给你更多研究方向选择! 2. 企业级综合实战项目,集六大前沿技术为一体 二. Python 2与Pyt ...

  9. 深度学习Anchor Boxes原理与实战技术

    深度学习Anchor Boxes原理与实战技术 目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的地面真实边界框.不同的模型 ...

  10. 整理AI性能指标

    整理AI性能指标 Sorting out AI performance metrics 推理性能的最佳衡量标准是什么? 在人工智能加速器的世界里,对于给定的算法,芯片的性能经常以每秒万亿次的运算量(T ...