ELF&PE 文件布局深入剖判

作者:必威体育网页进入    发布时间:2019-12-01 21:27    浏览:149 次

[返回]
typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD   Characteristics;    // 未使用,总为0 

    DWORD   TimeDateStamp;      // 文件创建时间戳
    WORD    MajorVersion;       // 未使用,总为0 

    WORD    MinorVersion;       // 未使用,总为0
    DWORD   Name;               // 指向一个代表此 DLL名字的 ASCII字符串的 RVA
    DWORD   Base;               // 函数的起始序号
    DWORD   NumberOfFunctions;  // 导出函数的总数

    DWORD   NumberOfNames;      // 以名称方式导出的函数的总数

    DWORD   AddressOfFunctions;     // 指向输出函数地址的RVA
    DWORD   AddressOfNames;         // 指向输出函数名字的RVA
    DWORD   AddressOfNameOrdinals;  // 指向输出函数序号的RVA

} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

ELF&PE 文件构造解析

说轻松题,ELF 对应于UNIX 下的公文,而PE 则是Windows 的可试行文件,解析ELF 和 PE 的文件布局,是逆向工程,或然是做调节和测验,以致是开荒所应具备的主干技巧。在进展逆向工程的上马,大家获得ELF 文件,或许是PE 文件,首先要做的便是解析文件头,精通音讯,进而逆向文件。不说废话,最初深入分析:

ELF和PE 文件皆以基于Unix 的 COFF(Common Object File Format卡塔尔(قطر‎校正而来,尤其具体的来讲,他是出自此时资深的 DEC(Digital Equipment Corporation卡塔尔(قطر‎ 的VAX/VMS 上的COFF文件格式。我们从ELF 说到。

AddressOfFunctions 所指向内容是以 4 字节为三个单位的数组成分,种种成分代表函数入口

ELF

ELF 文件规范里把系统中使用ELF 格式的文件归类为三种:

  • 可重平素文件,Relocatable File ,那类文件包含代码和多少,可用来连接成可试行文件或分享目的文件,静态链接库归为此类,对应于Linux 中的.o ,Windows 的 .obj.
  • 可施行文件,Executable File ,那类文件饱含了可以直接实施的主次,它的表示正是ELF 可推行文书,他们日常未有扩充名。比如/bin/bash ,Windows 下的 .exe
  • 分享目标文件,Shared Object File ,这种文件包括代码和数据,链接器能够动用这种文件跟其余可重一直文件的分享指标文件链接,发生新的对象文件。其它是动态链接器能够将多少个这种分享指标文件与可实施文件结合,作为进度印象来运作。对应于Linux 中的 .so,Windows 中的 DLL
  • 中央转储文件,Core Dump File,当进度意外终止,系统能够将该进度地址空间的始末及停止时的有的消息转存到骨干转储文件。 对应 Linux 下的core dump。

ELF 文件的少年老成体化结构大意上是那般的:

ELF Header
.text
.data
.bss
... other section
Section header table
String Tables, Symbol Tables,..
  • ELF 文件头放在最前端,它含有了任何文件的骨干质量,如文件版本,指标机器型号,程序入口等等。
  • .text 为代码段,也是反汇编管理的有个别,他们是以机器码的花样储存,未有反汇编的历程基本不会有人读懂那些二进制代码的。
  • .data 数据段,保存的那多少个曾经起首化了的全局静态变量风度翩翩对静态变量
  • .bss 段,寄存的是未初阶化的全局变量局部静态变量,那一个比较轻巧驾驭,因为在未初叶化的情景下,大家单独用一个段来保存,能够不在一开端就分配空间,而是在最后总是成可推行文件的时候,再在.bss 段分配空间。
  • 别的段,还会有意气风发对可选的段,比如.rodata 表示这里存款和储蓄只读数据, .debug 表示调试新闻等等,具体蒙受能够查阅相关文书档案。
  • 自定义段,这一块是为了促成客户独刻意义而存在的段,方便扩张,比如我们选取全局变量只怕函数以前拉长 **attribute(section('name'))** 就能够吧变量也许函数放到以name 作为段名的段中。
  • 段表,Section Header Table ,是一个第风流浪漫的局地,它描述了ELF 文件蕴涵的具备段的音信,譬喻各个段的段名,段长度,在文件中的偏移,读写权限微风流倜傥部分段的别样质量。

AddressOfNames 所指向内容是以 4 字节为一个单位的数组元素,每一种元素代表二个针对字符串的 福睿斯VA

ELF Header

ELF 文件消息的查看利器在Linux 下是是objdump, readelf, 相关命令超级多,可查。上面大家从ELF 文件头聊起。

文件头包括的剧情超级多,大家在Ubuntu 系统下使用 readelf 命令来查看ELF 文件头:

图片 1

我们以bash 那些可实施文件为例,大家能够看出ELF 文件头定义了ELF 魔数,文件机器字节长度,数据存款和储蓄格局,版本,运营平台,ABI版本,ELF 重定位类型,硬件平台,硬件平台版本,入口地址,程序头入口和长短,段表的岗位和长度,段的数据。

ELF 文件头的协会和血脉相仿常数经常定义在了 /usr/include/elf.h 中,大家得以步向查看一下:

图片 2

除去第三个,别的都是逐后生可畏对应的,第四个是二个应和了Magic number, Class, Data, Version, OS/ABI, ABI version.

出将来最早阶的ELF Magic number, 16字节是用来标记ELF 文件的平台属性,比方字长,字节序,ELF 文件版本。在加载的时候,首先会确认魔数的不易,不得法的话就拒绝加载。

另三个主要的东西是段表(Section Header Table),保存了五光十色段的主干品质,譬如段名,段长度,文件中的偏移,读写权限,段的别样板质。而段表本身在ELF 文件中的地点是在ELF 头文件 e_shoff 决定的。

咱俩得以选取 objdump -h 的授命来查看ELF 文件中包括如何段,以bash 那一个可进行为例,其实不外乎大家以前说的什么样基本构造,他带有众多别样的构造:

图片 3

无差距于的,大家运用readelf -S 的授命也足以扩充查看。

上面我们来看一下组织,照旧到elf.h 中去查看,他的布局体名字叫 Elf32_Shdr,64位对应Elf64_Shdr,构造如下:

图片 4

上述构造中,分别对应于:

  • 段名
  • 段类型
  • 段标记位
  • 段虚构地址
  • 段偏移
  • 段长度
  • 段链接
  • 段对齐
  • 项,一些朗朗上口固定的项,如符号表等。

这个项目,在运用readelf -S 指令时风度翩翩后生可畏对应。

此外还会有一个主要的表,叫重定位表,平常段名称为.rel.text, 在上方未有现身,链接器在管理指标文件时,需求对目的文件中的有些地方开展重从来,便是代码段和数码段中这一个对相对地址援用的岗位,那时候就须要运用重定位表了。

AddressOfNamesOrdinals 所指向内容是以 2 字节为三个单位的数组成分,每种成分代表对应名字在 AddressOfFunctions 中的序号数。

字符串表

怎会有字符串表呢?其实这么些也是在相连发展更上后生可畏层楼中找到的化解办法,在ELF 文件中,会用到很多的字符串,段名,变量名等等,但是字符串其本人又长度不定点,借使利用固定布局来代表,就能够带给空间上的辛苦。所以,布局三个字符串表,将采纳的字符串统风度翩翩放在此,然后经过偏移量来援用字符串,岂不美哉。

须要选取的时候,只供给给一个偏移量,然后就到字符串该岗位找字符串,蒙受 就停止。

字符串在ELF 文件中,也是以段的格局保留的,见惯司空的段名 .strtab, .shstrtab 四个字符串分别为字符串表和段表字符串,前面三个用来保存普通的字符串,后面一个保存段名。

在大家使用readelf -h 的时候,大家来看最终叁个分子,section header string table index ,实际上她指的就是字符串表的下标,bash 对应的字符串表下标为27,在应用objdump 的时候,实际上忽视了字符串表,大家运用readelf ,就可以以知道见第29人即字符串表:

图片 5


下边我们想起一下,那些ELF 布局的精致的地方,当三个ELF 文件到来的时候,系统本来的找到他的伊始,获得文件头,首先看魔数,识别基本音讯,看是否科学的,只怕是可识其余文件,然后加载他的大旨音讯,包含CPU 平台,版本号,段表之处在哪,还能够得到字符串表在哪,以至整个程序的输入地址。那意气风发多元开首化音信得到未来,程序可以通过字符串表定位,找到段名的字符串,通过段表的初叶地点,确认种种段的岗位,段名,长度等等音信,进而达到入口地址,计划奉行。

当然,那只是早先时期始的剧情,其后还要考虑链接,Import,Export 等等内容,留待现在康健。

AddressOfNames 和 AddressOfNamesOrdinals 的多少肯定是平等的,不是平等那么就出错了。

PE 文件

下边我们去寻访更为宽广的PE 文件格式,实际上PE 与 ELF 文件基本相符,也是运用了基于段的格式,同不时常间PE 也允许技士将变量只怕函数放在自定义的段中, GCC 中**attribute(section('name'))** 增添属性。

PE 文件的前身是COFF,所以深入分析PE 文件,先来看看COFF 的文件格式,他保留在WinNT.h 文件中。

COFF 的文件格式和ELF 差相当的少一毛雷同:

Image Header
SectionTable Image_SECTION_HEADER
.text
data
.drectve
.debug$S
... other sections
Symbol Table

文本头定义在WinNT.h 中,大家张开来看一下:

图片 6

小编们能够看来,它这些文件头和ELF 实际上是相像的,也在文件头中定义了段数,符号表的地点,Optional Header 的尺寸,这些Optional Header 前边就来看了,他正是PE 可实行文件的文本头的局地,以至段的性子等。

跟在文书头前面包车型地铁是COFF 文件的段表,布局体名称叫 IMAGE_SECTION_HEADER :

图片 7

属性包罗这几个,和ELF 没差:

  • 段名
  • 物理地址 PhysicalAddress
  • 虚构地址 VirtualAddress
  • 本来数据大小 Sizeof raw data
  • 段在文书中之处 File pointer to raw data
  • 该段的重定位表在文书中的地点 File pointer to relocation table
  • 该段的行号表在文件中的地点 File pointer to line number
  • 标识位,包蕴段的品种,对齐方式,读取权限等标记。

首要要调整三种检索函数入口地址的情势:

DOS 头

在大家深入分析PE 的先头,还应该有其它一个头要打听一下,DOS 头,必须要说,微软事儿照旧挺多的。

微软在创制PE 文件格式时,大家正在广泛使用DOS 文件,所以微软为了构思兼容性的题目,所以在PE 头的最前面还增添了四个IMAGE_DOS_HEADE昂科威 布局体,用来扩充已部分DOS EXE。在WinNTFS.h 里能够看来她的体态。

图片 8

DOS 头布局体的高低是40字节,这里边有三个举足轻重的积极分子,需求精晓,一个是e_magic 又见魔数,三个是e_lfanew,它只是了NT 头的偏移。

对此PE 文件来讲,那些e_magic,相当于DOS 具名都是MZ,传说是二个叫 MarkZbikowski 的开辟职员在微软布置了这种ODS 可实践文件,所以...

小编们以Windows 下的notepad++ 的可推行文件为例,在二进制编辑软件中展开,此类软件超级多,Heditor 张开:

图片 9

始发的七个字节是4D5A,e_lfanew 为00000108 注意存款和储蓄顺序,小端。

你以为开首加上了DOS 头就成功了么,就足以随着接PE 头了么。为了合营DOS 当然不是那样不难了,紧接着DOS 头,跟的是DOS 存根,DOS stub。这一块正是为DOS 而计划的,对于PE 文件,纵然未有它也能够健康运转。

图片 10

风度翩翩旁的ASCII 是读不懂的,因为她是机器码,是汇编,为了在DOS 下试行,对于notepad++ 来讲,这里是实行了一句,this program cannot be run in DOS mode 然后脱离。逗作者= =,有新的人,能够在DOS 中开创三个前后相继,做一些小动作。

搜索