oneself是什么意思 elf是什么意思


oneself是什么意思  elf是什么意思

文章插图
本文介绍了ELF的基本结构和内存加载的原理 , 并用具体案例来分析如何通过ELF特性实现HIDS bypass、加固/脱壳以及辅助进行binary fuzzing 。
前言作为一个安全研究人员 , ELF可以说是一个必须了解的格式 , 因为这关系到程序的编译、链接、封装、加载、动态执行等方方面面 。有人就说了 , 这不就是一种文件格式而已嘛 , 最多按照SPEC实现一遍也就会了 , 难道还能复杂过FLV/MP4?曾经我也是这么认为的 , 直到我在日常工作时遇到了下面的错误:
$ r2 a.outSegmentation fault作为一个开源爱好者 , 我的 radare2 经常是用master分支编译的 , 经过在github中搜索 , 发现radare对于ELF的处理还有不少同类的问题 , 比如 issue#17300 以及 issue#17379  , 这还只是近一个月内的两个open issue , 历史问题更是数不胜数 。
总不能说radare的开发者不了解ELF吧?事实上他们都是软件开发和逆向工程界的专家 。不止radare , 其实IDA和其他反编译工具也曾出现过各类 ELF相关的bug。
说了那么多 , 只是为了引出一个观点: ELF既简单也复杂 , 值得我们去深入了解 。网上已经有了很多介绍ELF的文章 , 因此本文不会花太多篇幅在SPEC的复制粘贴上 , 而是结合实际案例和应用场景去进行说明 。
ELF 101ELF的全称是 Executable and Linking Format  , 这个名字相当关键 , 包含了ELF所需要支持的两个功能——执行和链接 。不管是ELF , 还是Windows的 PE  , 抑或是MacOS的 Mach-O  , 其根本目的都是为了能让处理器正确执行我们所编写的代码 。
大局观在上古时期 , 给CPU运行代码也不用那么复杂 , 什么代码段数据段 , 直接把编译好的机器码一把梭烧到中断内存空间 , PC直接跳过来就执行了 。但随着时代变化 , 大家总不能一直写汇编了 , 即便编译器很给力 , 也会涉及到多人协作、资源复用等问题 。这时候就需要一种可拓展(Portable)的文件标准 , 一方面让开发者(编译器/链接器)能够高效协作 , 另一方面也需要系统能够正确、安全地将文件加载到对应内存中去执行 , 这就是ELF的使命 。
oneself是什么意思  elf是什么意思

文章插图
从大局上看 , ELF文件主要分为3个部分:
ELF HeaderSection Header TableProgram Header Table其中 ,  ELF Header 是文件头 , 包含了固定长度的文件信息; Section Header Table 则包含了 链接时 所需要用到的信息; Program Header Table 中包含了 运行时 加载程序所需要的信息 , 后面会进行分别介绍 。
ELF HeaderELF头部的定义在 elf/elf.h 中(以glibc-2.27为例) , 使用POD结构体表示 , 内存可使用结构体的字段一一映射 , 头部表示如下:
#define EI_NIDENT (16)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;注释都很清楚了 , 挑一些比较重要的来说 。其中 e_type 表示ELF文件的类型 , 有以下几种:
*.o*.soe_entry 是程序的入口虚拟地址 , 注意不是main函数的地址 , 而是 .text 段的首地址 _start。当然这也要求程序本身非PIE( -no-pie )编译的且ASLR关闭的情况下 , 对于非 ET_EXEC 类型通常并不是实际的虚拟地址值 。
其他的字段大多数是指定Section Header( e_sh )和Program Header( e_ph )的信息 。Section/Program Header Table本身可以看做是数组结构 , ELF头中的信息指定对应Table数组的位置、长度、元素大小信息 。最后一个 e_shstrndx 表示的是section table中的第 e_shstrndx 项元素 , 保存了所有section table名称的字符串信息 。

推荐阅读