首页
论坛
课程
招聘
[其他内容] [原创]换种方式理解 ELF 文件格式
2021-4-30 21:13 3121

[其他内容] [原创]换种方式理解 ELF 文件格式

2021-4-30 21:13
3121

这些天整理笔记,整理到 ELF 格式的时候,内心总是:这是我的笔记吗?我怎么会这么记笔记?又翻了一下虫神的 ELF 文件格式示意图,依旧一脑袋浆糊,所以打算从文件构造的角度理解 ELF 格式。

 

考虑一般 ELF 文件
我感觉要明白一个思维,计算机中存储的都是数据,无论是地址还是值,无论是简单类型还是复杂结构,总要有方法进行管理、访问、控制

 

首先,能很容易明白的是,ELF 可执行文件它是分 Section 的
每一种 Section 都有着不同的用处,其中比较重要的就是

  • .text -> 代码
  • .data -> 初始化的全局静态变量和局部静态变量
  • .rodata -> 只读变量和字符串常量
  • .bss -> 未初始化的全局变量和局部静态变量
  • .symtab -> 符号
  • .strtab -> 字符串
  • .plt,.got -> 动态链接的跳转和全局入口

暂且不考虑这些 Section 的细节,接下来能想到的是既然有 Section,计算机如何才能找到对应的 Section

 

那么就需要告诉计算机相应 Section 的完整属性,比如:

  • Section name -> 叫什么名字
  • Section type -> 所属类型
  • Section flag -> 能支持什么操作,写?读?执行?
  • Section size -> 大小
  • Section offset -> 在文件哪里?

这些属性合并在一起,代表着这个 Section,所以起了个名字叫 Section Header
举个不恰当的例子,你要想去公司里找特定部门谈生意,那你肯定的知道部门的名称,在公司的哪栋楼,多少人,能谈什么生意,谈生意的规则...

 

一个公司也不止一个部门,一个 ELF 文件也不止一个 Section,有时需要多找几个,怎么快速发现呢?此时,计算机的常见思维出现了,我需要找个管理来整合这些资料,是的,没错,将这些数据整合成表,变成了 Section Header Tables

 

现在有了 Section Header Tables,计算机就能够通过它访问各种数据,但是问题来了,对于 Section 来说,像类型、flag,size 等信息都能在相似的数据类型下良好的定义,名字该怎么半?名称的长短伸缩性不小,而且有些通用性并不高,如:

  • .init
  • .eh_frame
  • .gcc_except_table
  • __libc_thread_freeres_fn

如果不管不顾,那这个 Section Header Tables 也太乱了,会跟着名称来回波动,因此,就再构造一个名称表,把这些 Section 的名字都记录下来,如果想知道对应名称,就到这个表中取,如此一来,每个 Section Header 的大小也就可以固定了,真的整洁,于是乎,变成了 Section Header String Table, 把它也放在 Section Header Tables 中

 

同理,也想以固定的格式保存各个 Section 中的变量名,直接抄波代码,修改个表名,起名叫做 String Table

 

到现在,计算机已经能通过 Section Header Tables 获取很多信息了,

 

可是 ELF 也是有类型的,像可重定位文件,要执行就得链接,在链接过程中,当 A 中调用了 B 的函数,就像两个公司进行对接,你要对接的人永远不可能原地不动,如何像别的公司便携的告诉对接人的信息,那么就起个花名,比如 ”肉丝“,这样跑到该公司楼下一问便知,像某巴这么多花名,总不能肆意泛滥,随意起名,甚至可以脑袋一热,统一给花名修饰一下,丑是丑了点,可它不会撞名啊

 

同上,我再整个花名册,这下就方便对接了吧,效仿国际化,起个名字叫:Symbol Table, 也加到 Section Header Tables 里面吧。

 

哇咔咔,作为领导管理一个公司,不应该自顶向下吗?关注细节可不是你该干的事,所以,给你单独立一个模块,以后发名片好用,起个名字叫 ELF Header,里面拥有公司的各种基础信息。

 

这样的一个格式已经足够平时对外营业了,可是,作为大公司,要注重安全不是,平时的内部网络攻防也应该搞起来啊。这不得按业界习惯,学习虎符公司整个三件套,把公司部门组合成红蓝紫三队,Code Segment 负责攻击,Data Segment 负责防御,其他部门负责旁观、策划、后勤。作为演练攻防,当然要让老板近距离看到效果,那就离 ELF Header 近一点吧!结构嘛,也就仿效平时的部门结构吧!

 

整合一下,这就是公司的日常,哦不,ELF 的一般结构

 

至此,一个 ELF 文件的格式也基本分析结束,突然觉得,拿公司来举例真是好主意,感觉画漫画展示效果会更好!有没有大佬感兴趣,涂抹一两笔。

 

停笔,如果有时间,俺也来个图解 ELF 也是极好的

 

个人拙见,仅供参考,写此一文,博君一笑足以 orz


 

参考资料:
程序员的修养
CTF_all_in_one (再次膜拜大佬


第五届安全开发者峰会(SDC 2021)议题征集正式开启!

收藏
点赞4
打赏
分享
最新回复 (4)
雪    币: 222
活跃值: 活跃值 (375)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
滚动不息的球 活跃值 2021-4-30 23:15
2
0
才看到开头就很喜欢你这篇文章诶!~
雪    币: 43
活跃值: 活跃值 (161)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TX杀手 活跃值 2021-5-5 10:06
3
0
有什么用,30多岁也得失业
雪    币: 28
活跃值: 活跃值 (195)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
万抽抽 活跃值 2 2021-5-6 10:46
4
2
感谢楼主,总结得挺好,点赞!个人愚见,整个计算机体系架构,从最底层的硬件到最顶层的应用都充斥着:自底向上的概念抽象以及自顶向下的数据查询思想。就概念抽象而言,在最底层的指令集有抽象的操作码 opcode 和操作数 operands,并逐步向上抽象衍生到 -> 指令接口、数据接口 -> 内核 -> 驱动 -> 框架 -> 应用等;更进一步将里面的各层逻辑进行整合,就衍生出现在很火的 docker(硬件平台、系统、驱动以及部分必要框架整合在一起抽象为一个 docker 概念),SaaS, FaaS( docker + 应用层代码整合在一起) 等概念。就自顶向下的数据查询思想而言,其更是深入到计算机体系结构的基因里。应用层程序要想使用系统/三方库函数,得查询——按情况使用动/静态链接器查询对应的符号地址;库函数想要使用系统底层能力,得查询——依据 syscall id 进行查询;在硬件层,执行指令得从代码段依据 PC 进行查询,获取数据得依据 address 从寄存器/RAM 中查询,期间为了提高查询效率,还额外引入 cache 机制,比如提高数据查询效率的 data cache,提高指令查询效率的 instruction cache 等。回过头来,再来理解各种文件格式、架构设计貌似更清晰明了咯。
雪    币: 1092
活跃值: 活跃值 (586)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Emiya侍郎 活跃值 2021-5-6 14:53
5
0
万抽抽 感谢楼主,总结得挺好,点赞!个人愚见,整个计算机体系架构,从最底层的硬件到最顶层的应用都充斥着:自底向上的概念抽象以及自顶向下的数据查询思想。就概念抽象而言,在最底层的指令集有抽象的操作码 opcod ...
十分感谢,这是从宏观角度看整个计算机,你所说的这种思想确实是放在那里,可是个人感觉放在理解文件格式上面有点杀鸡用牛刀,而且人最容易记忆的就是形象化的东西,抽象的东西依旧是晦涩,比如说 ELF 格式,我所做的就是尽可能在不用理解原本文件格式设计原理的基础上能够长期的记住它的大概格式
游客
登录 | 注册 方可回帖
返回