ELF解析04 - 字符串表/导入库表/符号表/导入表

本文详细解读了DynamicSegment中的子表,特别是字符串表、导入库表和符号表的结构,以及重定位表(如plt和rela.plt)的工作原理,着重讲解了不同类型的重定位和链接器如何处理它们。

本文主要讨论 Dynamic Segment 里面的几个子表。

总体结构介绍

我们先总体看下 Dynamic Segment :

这里我们只需要关心图中两个画圆圈的地方。

第一个是虚拟地址

由于 Dynamic Segment 的子表内容都在可加载段的范围里面,所以对这些子表的访问都是在虚拟内存里面进行的。

p_offset_FROM_FILE_BEGIN 这个值我们可以自己静态分析使用,但是解析的时候不要用这个地址。包括 p_filesz_SEGMENT_FILE_LENGTH  p_memsz_SEGMENT_RAM_LENGTH,这些值都没用。

有一个需要注意的地方,就是p_offset_FROM_FILE_BEGIN 的值要比 p_vaddr_VIRTUAL_ADDRESS 的值要大一个 PAGE 值。这是为啥呢?

是因为第二个可加载段的映射偏差:

可以看到在第二个可加载段在做内存映射的时候就有一个 PAGE 值的偏差,由于只要是放在第二个段里面的内容,就会有一个 PAGE 的偏差。

第二个是子表

第二个画圈的地方说明了,子表有 39 项。但是实际上最后几项都是 NULL:

所以解析子表的时候,不会去先计算子表的大小,然后用 大小/sizeof(xxx) 这样的方式,而是直接从头开始解析,直到遇到 DT_NULL。

子表的结构体是 struct Elf64_Dyn :

typedef struct
{
  Elf64_Sxword d_tag;   /* Dynamic entry type */
  union
    {
      Elf64_Xword d_val;  /* Integer value */
      Elf64_Addr d_ptr;   /* Address value */
    } d_un;
} Elf64_Dyn;

一共16个字节,前8个字节表示类型,后8个字节表示地址(注意表示的是虚拟地址)或者整数值。

我们先研究字符串表,其 type 为 5:

字符串表

我们找到字符串表的虚拟地址位置 0x2328,它是在第一个段里面。其实这个地址也能在 section header 里面找到:

只不过 section header 里面的这个地址容易被篡改而已。

根据第一个段的mmap映射关系,我们知道,其文件位置也是 0x2328,我们跳过去看看:

明显看出,这里确实是字符串表。

这个表要如

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二手的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值