# Code Section

## 概述

在动态链接器创建了进程镜像，并且执行了重定位后，每一个共享目标文件都有机会去执行一些初始化的代码。所有的共享目标文件会在可执行文件获得权限之前进行初始化。

在调用目标文件 A 的初始化代码之前，会首先调用所有 A 依赖的共享目标文件的初始化代码。比如说，如果目标文件 A 依赖于另外一个目标文件 B，那么 B 就会在 A 的依赖列表中，这会被记录在动态结构的 DT\_NEEDED 中。循环依赖的初始化是未被定义的。

目标文件的初始化通过递归每一个被依赖的表项来完成。只有当一个目标文件依赖的所有的目标文件都处理完自己的依赖后，这个目标文件才会执行初始化代码。

下面的例子解释了两种正确的可以用来生成给定例子的顺序。在这个例子中，a.out 依赖于b，d 以及 e。b依赖于d 和 f，并且 d 依赖于 e 和 g。根据这个信息，我们可以画出如下的依赖图。那么我们上面所说的算法，将允许我们按照如下的顺序进行初始化。

![](/files/EbIGVbmoUhJg7np8WmmI)

类似的，共享目标文件也会有结束的函数，这些函数在进程完成自己的终止序列时通过 atexit 机制来执行。动态链接器调用终止函数的顺序恰好与上面初始化的顺序相反。动态链接器将会确保它只会执行初始化或者终止函数最多一次。

共享目标文件通过动态结构中的 DT\_INIT 和 DT\_FINI 来指定它们的初始化以及结束函数。在一般情况下，这些函数在.init节与.fini节中。

注意：

> 尽管ateixt终止处理函数通常来说会被执行，但它并不会保证在程序消亡时被执行。更特殊的是，如果程序调用了\_exit函数或者进程由于接收到一个信号后消亡了，那么它将不会执行对应的函数。

动态链接器并不负责调用可执行文件的 .init 节或者利用 atexit 注册可执行文件的 .fini 节。由用户通过 atexit 机制指定的终止函数必须在所有共享目标文件的结束函数前执行。

## .init & .init\_array

此节区包含可执行指令，是进程初始化代码的一部分。程序开始执行时，系统会在开始调用主程序入口（通常指 C 语言的 main 函数）前执行这些代码。

## .text

此节区包含程序的可执行指令。

## .fini & .fini\_array

此节区包含可执行的指令，是进程终止代码的一部分。程序正常退出时，系统将执行这里的代码。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ctfwiki.stinger.team/executable/elf/structure/code-sections.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
