可执行部分标题 - 含义和用途?

Executable Section Headers - Meaning and use?

提问人:KeyC0de 提问时间:2/18/2017 最后编辑:KeyC0de 更新时间:3/16/2017 访问量:6598

问:

通过使用 7zip 在 Windows 中打开许多可执行 (, ) 文件,我注意到许多不同的文件类型很常见。其中包括 .text、.data、.bss、.rdata、.pdata 等。我试图获得有关它们的信息,但我无法找出它们的含义。以下是其中的一些:.exe..msi

  • .text:代码部分,包含程序的指令 - 只读 - 。
  • .data:通常用于具有一些初始化非零内容的可写数据。因此,数据部分包含在应用程序执行期间可能更改的信息,并且必须为每个实例复制此部分。
  • .bss:用于初始化为零的可写静态数据。
  • .rdata:任何类型的常量/只读数据都存储在此处。
  • .edata:导出目录、描述符和句柄
  • .idata:句柄和描述符的导入目录。可执行文件(exe、dll 等)使用它来指定导入和导出的函数。
  • .rsrc:包含有关可执行文件所需的各种其他资源的信息的部分,例如在资源管理器中查看可执行文件时显示的图标

还有很多其他的,很常见,我找不到任何信息。大多数是:、、、证书、、、。.pdata.tls.reloc.rsrc_1.aspack.adata.INITDATACODE.ctors

其中大多数还包含一个文件夹,其中包含 BITMAP、CURSOR、ICON、GROUP_CURSOR、GROUP_ICON、MENU、VERSION 等文件夹。rsrc

一些可执行文件还包含更多的可执行文件,文件,文件等。我还打开了一个什么都没有的东西(至少用 7zip 打开它什么也没显示)![我用7zip打开了它们。.html.txt


问题

  1. 我发布的那些部分/细分是做什么的?有没有一个网站可以让我找到它们?
  2. 我看的都是 Windows 的 PE。这些格式是否是标准的,并以类似/相同的方式适用于 LINUX、UNIX 等?
  3. 为什么某些可执行文件在.html、.txt和其他文件中包含其他可执行文件?启动可执行文件时如何处理这些内容?他们应该做什么?AFAIK 可执行文件中的所有内容都应仅具有类似于汇编代码部分的“段”。
  4. 文件夹有什么用?它拥有什么样的资源?rsrc

如果您能发布更多信息/链接,说明为什么使用所有这些(尽可能低级别)以及可执行结构应该是什么样子,它应该包含什么等,我将不胜感激。

仅此而已。


编辑

我找到了其他常见的部分标题名称。为了完整起见,我将在这里发布它们的含义。

  • .reloc:包含重定位表。
  • .pdata:包含用于异常处理的函数表条目数组,并由图像数据目录中的异常表条目指向
  • *data:自定义数据部分名称
  • .init:此部分包含有助于进程初始化代码的可执行指令。也就是说,当一个程序开始运行时,系统会安排在主程序入口点(在 C 程序中称为 main)之前执行本节中的代码。
  • .fini:此部分包含有助于进程终止代码的可执行指令。也就是说,当程序正常退出时,系统会安排执行本节中的代码。
  • .ctors:保留构造函数列表的部分
  • .dtors:包含析构函数列表的部分
程序集 exe 便携式可执行

评论


答:

2赞 old_timer 2/18/2017 #1

这里没有魔法,也没有关于构建可执行文件的通用规则。您必须遵循相关操作系统的规则,并仅向其提供它理解的可执行格式。但即便如此,尽管这些部分在几十年的时间里在编译器中非常普遍地使用,但在技术上是任意的。你基本上完成了你需要做的所有工作,并回答了你自己的问题。

操作系统只需要知道几件事。这个文件中有多少是实际可加载的数据,以及我在哪里加载它。操作系统不知道/看到 .data 中的 .text,它看到的是可加载的块。它将这些块从文件复制到内存中,然后看到一个定义的入口点,它分支到该入口点。其余信息是...信息。。。对于调试器来说,无论是软件还是有兴趣查看编译器在 .data 部分中放置了多少或什么的人,例如。

正确使用这些部分直接或间接取决于程序员,通常程序员不会直接参与。称为引导程序的软件可根据需要执行处理这些部分的工作。例如,引导程序通常将 .bss 部分归零,这是编译器工具链中的系统设计解决方案,它告诉引导程序 .bss 的大小和起始地址,而引导程序则将 ram 归零。

.data 和 .text 通常只是由操作系统加载,不需要进一步关注,因为它们正在加载到 RAM 中。但是,例如,如果这是一个微控制器,我们需要将非零全局 .data 放在非易失性存储器(闪存/rom)中,但是当我们启动并运行编译的代码时,我们需要它在 ram 中。因此,引导程序通常使用编译器系统设计解决方案来完成将 .data 从闪存复制到 ram 的工作,该解决方案告诉引导程序闪存中的起始地址和 ram 中的起始地址以及要复制的量。

我所说的系统设计是一个变量,如果你愿意的话,汇编语言(否则就是一个先有鸡还是先有蛋的问题)引导程序使用,在链接器完成其工作并弄清楚有多少东西以及它们在二进制或内存映像中的位置后,由链接器填充。

数据就是数据,您可以将数据嵌入到二进制文件中,无论是文本或html还是图像(jpg,bmp,png等)或其他,正确的hexdump工具可以显示,使用的工具链甚至可能具有该数据的特殊部分名称。

几乎所有这些部分名称都部分用于调试编译器输出,部分用于信息。一个特定的工具链有它使用的特定部分名称,甚至可能允许用户(程序员)创建自己的任意名称,因为这就是它们的全部。该特定工具链使用该信息作为其系统设计的一部分,编译器从数据中筛选出程序,并且它不必在开始全局数据时从假定为零的非零全局数据中分离出非零全局数据。也许比这更深,只读取非零数据。它使用名称标记这些对象 Blob,以便链接器可以收集所有命名的 Blob,并使用链接器脚本将这些 Blob 组合成更大的 blob 并为其分配地址。然后根据需要修补二进制文件以解析外部地址/变量。

问题 1:不,没有网站可以找到它们,即使不容易证明至少有一个工具链允许用户发明自己的部分名称,那么很有可能,因为一个或多个网站不可能涵盖所有可能的部分名称和某些程序员可能想到的那些部分名称的定义。

问题 2:有一个通用的集合 .text、.data、.bss,它们已被所有目标系统(windows、unix 等)上的大多数(如果不是全部)工具链采用和使用,这是工具链的功能,而不是操作系统的功能,因为操作系统不知道也不关心。它只是将可加载的 blob 和分支加载到入口点。由于这些名称是任意的,并且只能在工具链的系统设计中工作,因此询问操作系统是没有意义的

问题 3:所有部分,无论是否奇怪,都由工具链间接管理,或链接在库中或由程序员直接管理。从 .bss 到 .somethingimadeup。

问题 4:这听起来是特定于操作系统的。了解操作系统定义了支持的可执行格式是什么以及它们由什么组成。编译器必须符合这一点才能制作有效的二进制文件。例如,像 Windows 这样的操作系统可能非常希望在“二进制文件”中有一个图标位图,这样它就可以在桌面上的程序名称旁边显示它,这也是二进制文件中的信息。因此,除了二进制文件格式需要具备的明显功能(文件偏移量和可加载数据 blob 的大小和内存中的目标地址以及执行入口点)之外,文件格式还可能具有其他信息或其他项。“Windows 快捷方式”的文件格式可能是子集或特殊的“二进制”格式,其信息是另一个文件的路径和文件名,而不是您实际加载和运行的代码。或快捷方式,例如您可能具有包含 URL 的“二进制”文件格式。但这在很大程度上取决于操作系统的定义和依赖性。

8赞 Hans Passant 2/18/2017 #2

部分名称与文件格式无关,工具链(通常链接器)可以选择它喜欢的任何内容。操作系统不使用名称来查找它关心的部分,它使用文件头中的数据目录。它包含数字,而不是名称。该名称仅用作助记符,以帮助识别部分。或者可用于帮助语言运行时或调试器查找数据目录未涵盖的部分。

部分名称有一定的一致性,主要是按照约定。像 BSS 这样的怪人部分名称可以追溯到 50 年代,用于 Fortran,这是 Block Started by Symbol 的首字母缩写词。猜测它今天的使用情况没有多大帮助:)您可以假设名为 CODE 的部分将包含可执行代码,并且等效于 .text,这是更常见的名称选择。像 .tls 和 .reloc 这样的名称可以映射到相应的数据目录条目,而不会遇到太多麻烦。

与 .rsrc 的接收相同,映射到数据目录中的第三个条目。对操作系统很重要,像 LoadString 这样的 winapi 函数需要它。

但是,只有详细了解工具链才能真正提示您了解奇怪的工具链。

操作系统加载程序通过使用可执行文件作为后备存储的内存映射文件将节直接放入虚拟内存中。这就是 .text、.data 和 .bss 等部分的使用方式,请注意它们在数据目录中没有相应的条目。链接器负责生成正确的地址,就像 25+ 年前完成的方式一样,不需要操作系统的帮助。除了 .reloc 部分(如果文件无法映射到其首选基址)之外,该文件已旧。

评论

0赞 KeyC0de 2/18/2017
非常有启发性的答案先生。这个链接是我想要的,它提供了所有信息。我还发现了许多其他常见的部分标题名称,我将将它们全部发布在上面,以区分它们在数据目录中的对应位置。关于你和old_timer都提到的“工具链”的另一个问题。我知道它是什么,但你到底指的是什么?AFAIK在构建过程中使用工具链,启动可执行文件时不涉及链接器,仅涉及加载器,将其加载到RAM中。您能详细说明一下这个“工具链”吗?多谢。
0赞 Hans Passant 2/18/2017
您可以使用工具链来构建程序。至少是编译器和链接器,也许是资源编译器等其他工具。有些语言将所有这些工具组合在一个可执行文件中,任何事情都可以。输入是源代码,输出是可执行文件。