如何将文本段设为只读?

2023-12-14

我知道文本段是只读段,尝试写入它会导致“总线错误”。 我很好奇这个段是如何变成只读的。

由于物理内存不是只读的,因此必须在分页期间完成此操作。

内存的每个页面是否都有一个位用于为文本段设置的只读页面?


ELF 文件(Unix 可执行文件或共享对象)有两个主要概念:

Section:可执行文件内具有特定作用的区域。 ELF 文件内可能有不同的部分(可以在man elf)。 ELF 文件中的常见部分有:

  • .text(SHT_PROGBITS):ELF 文件中的实际可执行代码。
  • .dynsym(SHT_DYNSYM):保存有关应动态检索的符号的信息。
  • .rela.dyn and .rela.plt(SHT_RELA):保存动态链接器在将 ELF 文件加载到内存时使用的重定位信息。
  • .dynamic(SHT_DYNAMIC):保存动态链接器的信息,例如其他依赖项、运行时不同部分的偏移量等。
  • .symtab(SHT_SYMTAB):保存符号表。
  • .strtab(SHT_STRTAB):保存字符串表。

还有更多的部分,以上只是一些常见的部分。

Using readelf人们可以看到 ELF 文件中的所有部分:

readelf --sections -W <file>

在我的计算机中的共享对象上运行此命令会产生以下输出(简化):

There are 29 section headers, starting at offset 0x1898:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
...
  [ 3] .dynsym           DYNSYM          0000000000000230 000230 000168 18   A  4   2  8
  [ 4] .dynstr           STRTAB          0000000000000398 000398 0000b0 00   A  0   0  1
...
  [ 7] .rela.dyn         RELA            0000000000000488 000488 0000c0 18   A  3   0  8
  [ 8] .rela.plt         RELA            0000000000000548 000548 000030 18  AI  3  22  8
...
  [12] .text             PROGBITS        00000000000005e0 0005e0 000121 00  AX  0   0 16
...
  [20] .dynamic          DYNAMIC         0000000000200e18 000e18 0001c0 10  WA  4   0  8
...
  [23] .data             PROGBITS        0000000000201028 001028 000008 00  WA  0   0  8
...
  [27] .symtab           SYMTAB          0000000000000000 001068 000570 18     28  45  8
  [28] .strtab           STRTAB          0000000000000000 0015d8 0001c6 00      0   0  1

Segment:可执行文件内的一个区域,包含动态链接器的加载指令。意思是,段只是 ELF 文件内的一个区域,应该加载到首选地址内存中,并具有特定的权限、对齐方式等。

每个部分(ELF 文件中具有逻辑角色的区域)都应该是段的一部分,具有正确的权限和特征。一个段内可以包含多个段,并且一个段位于单个段内(一对多关系)。

Using readelf我们可以看到 ELF 文件中的所有段:

readelf --segments -W <file>

在我的计算机中的共享对象上运行此命令会产生以下输出:

There are 7 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x00079c 0x00079c R E 0x200000
  LOAD           0x000e00 0x0000000000200e00 0x0000000000200e00 0x000230 0x000238 RW  0x200000
  DYNAMIC        0x000e18 0x0000000000200e18 0x0000000000200e18 0x0001c0 0x0001c0 RW  0x8
  NOTE           0x0001c8 0x00000000000001c8 0x00000000000001c8 0x000024 0x000024 R   0x4
  GNU_EH_FRAME   0x000718 0x0000000000000718 0x0000000000000718 0x00001c 0x00001c R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x000e00 0x0000000000200e00 0x0000000000200e00 0x000200 0x000200 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
   01     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
   02     .dynamic 
   03     .note.gnu.build-id 
   04     .eh_frame_hdr 
   05     
   06     .init_array .fini_array .jcr .dynamic .got 

在这里,我们可以看到所有与可执行代码相关的部分,以及许多与文件动态加载相关的部分都在段00(PT_LOAD)中,该段具有读取和可执行权限(R E)。加载程序应修改的部分位于段 01 (PT_LOAD) 中,该段具有读写权限(RW)。段 02 的类型为 PT_DYNAMIC,保存动态链接信息 -.dynamic部分。

动态链接器在将 ELF 文件加载到内存中时会考虑所有这些信息。它将 ELF 文件的不同段从磁盘加载到内存中,并使用正确的权限保护它们的页面。然后,它迭代不同的部分并根据它们的角色使用它们(重定位、解析动态符号等......)。

内存保护本身是由操作系统和硬件本身进行的。与使用Linux方法类似保护()。有关内存保护的更多信息可以找到here.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将文本段设为只读? 的相关文章

  • 是否可以从 C++ 应用程序调用 C# 应用程序?

    我是一名编程学生 现在我已经上了两门 C 课程 这个学期我将参加我的第一门 C 课程 出于好奇 是否可以从 C 应用程序调用 C 应用程序 如果是的话 是否还可以检查运行该程序的计算机是否具有 NET框架 我只是很好奇 我想如果可能的话 这
  • 无法将 std::min 传递给函数,std::min 的副本有效

    Passing std min函数无法编译 我复制了 libcpp 声明std min进入我的源文件并且它可以工作 std 版本有什么问题 clang 和 gcc 也会发生同样的情况 在 Godbolt 上测试 https godbolt
  • 锁定 ASP.NET 应用程序变量

    我在 ASP NET 应用程序中使用第三方 Web 服务 对第 3 方 Web 服务的调用必须同步 但 ASP NET 显然是多线程的 并且可能会发出多个页面请求 从而导致对第 3 方 Web 服务的同时调用 对 Web 服务的调用封装在自
  • XPATH 查询、HtmlAgilityPack 和提取文本

    我一直在尝试从名为 tim new 的类中提取链接 我也得到了解决方案 给出了解决方案 片段和必要的信息here https stackoverflow com questions 2982862 extracting a table ro
  • 并行化斐波那契序列生成器

    我正在学习并行化 在一项练习中 我得到了一些我应该提高性能的算法 其中之一是斐波那契数列生成器 array 0 0 array 1 1 for q 2 q lt MAX q array q array q 1 array q 2 我怀疑 这
  • 使用 Grep 查找两个短语之间的文本块(包括短语)

    是否可以使用 grep 来高亮所有以以下内容开头的文本 mutablePath CGPathCreateMutable 并以以下内容结尾 CGPathAddPath skinMutablePath NULL mutablePath 这两个短
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • 司机和提供商之间的区别

    数据库中的驱动程序和提供程序有什么区别 有没有解释一下 不胜感激 样本 ADO NET driver for MySQL vs providerName System Data EntityClient 来自 MSDN 论坛 驱动程序是安装
  • C# 处理标准输入

    我目前正在尝试通过命令行断开与网络文件夹的连接 并使用以下代码 System Diagnostics Process process2 new System Diagnostics Process System Diagnostics Pr
  • 将下拉列表与字典绑定

    我将字典绑定到下拉列表 举例来说 我的字典中有以下项目 Test1 123 Test2 321 我希望下拉文本采用以下格式 Test1 Count 123 Test2 Count 321 我沿着以下路径走 但没有运气 MyDropDown
  • C 中“complex”的默认类型

    根据我读过的文档 C99 和更高版本的支持float complex double complex and long double complex作为复杂类型 但是 此代码在使用时编译时不会发出警告gcc Wall Wextra inclu
  • 如何使用 Roslyn 通过扩展方法、静态类中的方法以及带有 ref/out 参数的方法来访问调用

    我正在致力于创建一个开源项目 用于创建 NET UML 序列图 该项目利用名为 js sequence diagrams 的 javascript 库 我不确定 Roslyn 是适合这项工作的工具 但我想我应该尝试一下 所以我整理了一些概念
  • 你好,我最近正在开发我的新游戏,我遇到了*无限跳跃*的问题

    所以基本上当我按跳跃 空格键时我会跳跃但是如果我连续按空格键它 只是跳啊跳啊跳等等 我不想要我只想它跳一次 code if Input GetKeyDown space isGrounded velocity y Mathf Sqrt ju
  • 用于连接 DataTable 上的动态列的动态 LINQ

    我目前遇到的情况不确定如何继续 我有两个从数据库填充的数据表 我还有一个可用的列名称列表 可用于将这两个数据表连接在一起 我希望编写一组 LINQ 查询 这些查询将 显示两个数据表中的行 内部联接 用于从一个数据表更新另一个数据表 显示一个
  • Xamarin - SignalR 挂在连接上

    我正在尝试将我的 Xamarin 应用程序连接到托管在 Azure 上的 SignalR 后端 我遇到的问题是每次我在 HubConnection 上调用 StartAsync 时 它都会挂起客户端并且请求永远不会完成 我尝试通过应用程序进
  • 无法为 wsdl 文件创建服务引用

    I have wsdl文件和xsd我本地机器上的文件 我想在项目中添加服务引用 我没有网络服务 我只有wsdl file 我收到以下错误 The document was understood but it could not be pro
  • C++ 到 C# 事件处理

    所以我有我的C WinForm 应用程序 我从中调用我的C CLI MFC dll图书馆 但也有一些events在我的 C 库上 甚至此事件也发生在该库的本机 非 CLI 部分 我需要从我的 C 应用程序调用一些代码 并获取一些有关此事件的
  • printf或iostream如何指定点后的最大位数

    字符串采用什么格式printf or iomanip我应该使用 iostream 中的运算符以以下格式打印浮点数 125 0 gt 125 125 1 gt 125 1 125 12312 gt 125 12 1 12345 gt 1 12
  • 使用 C# 动态创建按钮并按预定义的顺序放置它们

    NET 4 5 C 创建 Windows 窗体 我想动态创建和添加按钮并为其分配单击事件 但希望它们以特定的方式动态放置 就像图像一样 我的问题是如何以上述方式动态放置按钮 即 4x4 格式 一行 4 个按钮 4 列 但行数不受限制 是否可
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost

随机推荐