【gcc编译优化系列】各操作系统平台下的可执行文件格式介绍

您所在的位置:网站首页 文件命名有哪些格式的 【gcc编译优化系列】各操作系统平台下的可执行文件格式介绍

【gcc编译优化系列】各操作系统平台下的可执行文件格式介绍

2024-07-13 10:45| 来源: 网络整理| 查看: 265

目 录

一 重要知识点

二 本文重点内容

三 gcc相关知识补充

四 Windows 系列(Win7、Win8.1、Win10…)

五 Linux 系列(Ubuntu、RedHat、Kali Linux…)

六 Mac 系列(MacOS & iOS)

七 更多分享

一 重要知识点

- 可执行文件指的是可以由操作系统进行加载执行的文件;

- 可执行文件的文件格式常见有:    exe 和 dll(Windows 系列)、elf(Linux 系列)和 Mach-O(Mac系列);

- 可执行文件的 “格式”,和 “后缀” 二者没有直接关系,    事实上 Linux 下如 elf 类型是没有后缀名的;

- 可执行文件的 “执行” 二字,从直接执运行和间接调用两方面理解;

- 通用对象文件格(COFF,Common Object File Format)是这些 Unix-Like 系统可执行文件(如可执行的 elf、PE)的共同祖先,如今已被继承取代。

## 可执行文件结构学得好,对以后搞加密破解都是很有帮助的 ##

二 本文重点内容

主要包括:

Windows的PE文件 Linux的elf文件 Mac的macho文件 参考:维基百科 - 不同类型的可执行文件

三 gcc相关知识补充 /**********************************************************************  只编译不链接,生成二进制对象文件,后缀名在windows下为obj,在Unix-like下为o  如果想要生成可执行文件,还需要将这些文件进行链接操作。 **********************************************************************/ gcc -c /********************************************************************** 直接生成可执行文件,包含了前面提到的生成object file的过程, 缺点是看不到编译的细节,想要看编译细节还请使用别的指令参数。 **********************************************************************/ gcc

区别和联系:不同系统文件后缀名(只有 Windows 才有后缀名,Unix-Like 那叫假后缀名,这里写是为了方便理解)

Windows的obj文件,相当于Unix-Like的o文件 Windows的dll文件,相当于Unix-like的so文件 Windows的lib文件,相当于Unix-Like的a文件 Windows的PE文件,基本相当于Unix-Like的elf或mach-O文件 注意上面写的是 Unix-Like,也就是包括了 Linux 和 Mac 两个系列。我们说 Windows 的 PE、Linux 的 elf、Mac 的 mach-O,因为它们三者是对应的,是同一层次的。PE、elf、mach-O,不单单指的是某一个类型,它们指的是一类类型。比如 Windows 的 PE 文件,又可以分为 exe 文件和 dll 文件等… Linux 和 Mac 也可以进行类似的划分。而之所以把 Windows PE 单独拿出来讲,讲 exe,讲 dll,是因为 Windows 讲究文件后缀名,而 Unix-Like 的 OS 并没有这方面习惯。其实要划分也是可以划分的。

四 Windows 系列(Win7、Win8.1、Win10…)

PE 格式,可移植可执行格式(Portable Executable), 是 Windows 下的主要可执行文件格式。别被名字迷惑了,PE 文件必须是 Windows 下的文件。

在 Windows 下,exe 格式文件的后缀名就是 exe, 同理,dll格式文件的后缀名就是dll…(Windows比较注重文件后缀名)。

不过 obj 文件虽然叫obj文件,其实格式是COFF… 这点提请注意下…(唤做 COFF object)

PE(Portable Executable)格式,是微软 Win32 环境可移植可执行文件(如exe、dll、vxd、sys 和 vdm 等)的标准文件格式。PE 格式衍生于早期建立在VAX(R)VMS(R)上的COFF文件格式(前面有讲)。其中 portable 是指对于不同的 Windows 版本和不同的 CPU 类型上 PE 文件的格式是一样的,当然 CPU 不一样了,CPU 指令的二进制编码是不一样的。只是文件中各种东西的布局是一样的。

PE 格式… 这有个方便理解的简化版本

在这里插入图片描述

如同 ELF 存在的 ELF 头(本文后面讲),PE 格式文件也有 PE 头(PE header),而且加以区分 PE 格式还在文件的最上面加上了 MS-DOS 头部(DOS MZ header)… PE文件的第一个字节起始于MS-DOS头部,被称作IMAGE_DOS_HEADER。

紧随 DOS 头的,是 PE 头。PE Header 是 PE 相关结构 NT 映像头(IMAGE_NT_HEADERS)的简称,其中包含许多PE装载器用到的重要字段

包括:

程序入口点(OEP,Original Entry Point)文件偏移地址(File Offset)虚拟地址(VA,Visual Address)基地址(ImageBase,这个单词记住)相对虚拟地址(RVA,Relative Virual Address)

文件偏移地址是指数据在PE文件中的地址,是文件在磁盘上存放时相对于文件开头的偏移。文件偏移地址从 PE 文件的第一个字节开始计数,起始值为 0。用十六进制工具(如 WINHEX)打开文件所显示的地址就是文件偏移地址。对于一个确定的文件,基地址可能变化这是由编译器决定的,而偏移是固定的。通常认为 EXE 文件的基地址都是 0x00400000,而 DLL 文件的基地址都是 0x0010000(这两个量要记住)。

相对虚拟地址 - 虚拟地址 = 基地址

具体 PE 格式的结构体定义可以在编译器的 include 文件夹里的 WinNT.h 找到。在 Window 下的MinGW,相当于 Linux 的 gcc。你可以在这里找到它的源码,看看结构体是如何定义的。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述 

复杂版 PE 结构图,呵呵呵

在这里插入图片描述

在这里插入图片描述 

 在这里插入图片描述

PE 文件执行时,和进程的映射关系

在这里插入图片描述

最后放两张总结性的图

在这里插入图片描述在这里插入图片描述

 

当可执行文件执行起来,跑起来,就和系统内存挂钩。不管是 Windows 还是 Linux,每个程序分配 4G 的虚拟内存。不是真的分配这么多,这是允许访问的最大内存,况且 4G 中大概 2G 留给操作系统,剩下的还不到 2G。物理地址的内存空间属于底层,由操作系统负责,而进程属于用户;进程的虚拟内存空间和物理内存空间之间存在看不见的地址映射关系。

 而从虚拟地址通过页表映射到物理地址的过程,就是页表映射。

在这里插入图片描述

在这里插入图片描述

好好理解上面的这个过程, 不仅是 Windows,对学习 ELF 等 Linux 文件执行也是有帮助的。

Windows 下审核PE文件内容的方法 常用工具:PEView

PEView 本身是一个 exe 文件。

在这里插入图片描述在这里插入图片描述 五 Linux 系列(Ubuntu、RedHat、Kali Linux…)

elf 格式,可执行可链接格式(Executable and Linkable Format), 是 Linux 下的主要可执行文件格式。

elf格式文件包括 二进制文件、可执行文件、目标代码、共享库和核心转储格式文件;

因为Unix-Like不关心文件后缀名,所以实际上你可以给它们分别取任何你想要取的后缀名字,比如将Linux下可执行文件后缀写成execute,目标代码文件后缀写成object等… 这不重要。

elf 文件四个部分。其中:

包括三个索引表

ELF 文件头:ELF file header,位于文件开头,描述了文件组织情况。程序头表:program header table,告诉系统如何创建进程映像。用来构造进程映像的目标文件必须具有程序头部表,可重定位文件不需要这个表节头表:section header table:包含了描述文件节区的信息,每个节区在表中都有一项,每一项给出诸如节区名称、节区大小这类信息。用于链接的目标文件必须包含节区头部表,其他目标文件可以有,也可以没有这个表。

以及作为主体部分的节们 节:section、section、section、section…

使用下面的命令生成可重定位目标文件。“可重定位” 的意思是,“文件里面的代码段和数据的地址还没有最终确定”。默认生成的文件名为 cc.o。cc.c 是你事先写好的 C 语言源代码。

gcc -c cc.c

在这里插入图片描述使用下面的命令生成a.out,它本质上是一个可执行共享对象文件。在有的机子上可能有点不一样,显示的不是 shared object,或者显示为 executable,你要知道它们本质上没有什么不同:

在这里插入图片描述

对于 elf 格式文件,其中共享对象文件(shared object)和可执行类型文件(executable)没什么不同,唯一的区别就是,在编译时,前者可以被后者链接,而后者不能被前者链接(“共享” 的意思)。

在这里插入图片描述 上面生成的两个文件cc.o和a.out有什么不同呢?首先.o文件通常是没有program header table 的(或者说不是必须的),而由编译器将一个或多个.o文件链接编译后生成 program header table,前面说过 program header table 的作用是,文件载入内存执行时,是以 segment 组织的,每个 segment 对应 ELF 文件中 program header table 中的一个条目,用来建立可执行文件的进程映像。

在这里插入图片描述 

这里引入一个新的概念:segment。赛格门特毕竟也不是什么魔鬼?, 本质上 segment 和 section 不过是对同一部分 ELF 文件的不同描述罢了。

在这里插入图片描述 对于目标代码文件(.o),用 section 进行概括它的各个 “部分”,比如我们熟悉的 “data section”、“text section”、“bss section” 等(最基本的三个 section);至于可执行文件(用什么作后缀好呢,就是前面的那个 a.out),编译器将它的各个 section 又进一步整合,这些更大区间的 “部分” 叫 segment。目标代码文件视图(左边),program header table 是可选的,而可执行文件(右边),section header table 是可选的。

sections存储了程序链接时需要的信息,而 segment 存储了程序运行时需要的信息。

1 个 segment 可以包含 0 个或多个section。如下图所示, PHDR 段没有 section,而 LOAD 段含有多个 section。

在这里插入图片描述在这里插入图片描述 >>> section 和 segment 的中文翻译,以后不作说明,将 section 称为节,将 segment 称为段。比如下面的这个小例子,分别表示了文本段和数据段。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3