代码(.text)是否仅执行? .rodata是否可执行? [英] Code (.text) not execute-only? .rodata is executable?

查看:151
本文介绍了代码(.text)是否仅执行? .rodata是否可执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解ELF段是如何进行内存映射的。我注意到,各个部分都映射到相同的ELF段。例如,.rodata与.text映射到相同的段。

I am trying to understand how ELF segments are memory mapped. I noticed that various sections are mapped to the same ELF segment. For example, .rodata is mapped to the same segment as .text.

为什么会这样?为什么不将.rodata映射到单独的只读段而不是可执行段?

Why is this the case? Why not map .rodata to a separate read-only and not executable segment?

此外,将.text段映射到仅执行段意味着什么? (不可读)?

Also, what does it entail to map the .text section to an "execute ONLY" segment (not readable)? Are there any kernel/HW limitations that may hinder this?

编辑:
我还可以补充一点,我正在使用GNU链接器,如果这样会使

I may as well add that I am using the GNU linker, if that makes a difference.

推荐答案

从上面的评论中收集

它不能在包括x86-64在内的几种计算机体系结构上将内存标记为可执行但不可读。

It is not possible on several computer architectures, including x86-64, to mark memory as executable but not readable.

虽然x86 16位和32位确实允许在传统模式下进行分段,但是内存从理论上讲,可以使用段将内存标记为仅可执行文件,而平面地址空间的好处是如此之大,以至于x86-64现在基本上忽略了其段寄存器

While x86 16- and 32-bit did allow segmentation in legacy modes, and memory segments could in theory be used to mark memory as executable-only, the benefits of a flat address space were so great that x86-64 now mostly ignores its segments registers:


3.2.4在IA-32e模式下进行分段


在Intel 64体系结构的IA-32e模式下,细分的效果取决于过程是否essor在兼容模式或64位模式下运行。在兼容模式下,分段的功能与使用传统16位或32位保护模式语义时的功能相同。

3.2.4 Segmentation in IA-32e Mode

In IA-32e mode of Intel 64 architecture, the effects of segmentation depend on whether the processor is running in compatibility mode or 64-bit mode. In compatibility mode, segmentation functions just as it does using legacy 16-bit or 32-bit protected mode semantics.

在64位模式下,分段通常(但不完全)被禁用,创建一个平面的64位线性地址空间。处理器将CS,DS,ES,SS的段基数视为零,从而创建一个等于有效地址的线性地址。 FS和GS段是例外。这些段寄存器(保存段基)可以用作线性地址计算中的其他基寄存器。它们有助于处理本地数据和某些操作系统数据结构。

In 64-bit mode, segmentation is generally (but not completely) disabled, creating a flat 64-bit linear-address space. The processor treats the segment base of CS, DS, ES, SS as zero, creating a linear address that is equal to the effective address. The FS and GS segments are exceptions. These segment registers (which hold the segment base) can be used as additional base registers in linear address calculations. They facilitate addressing local data and certain operating system data structures.

请注意,处理器不会在运行时以64位模式执行段限制检查。

Note that the processor does not perform segment limit checks at runtime in 64-bit mode.

因此,内核只需将其段设置为覆盖整个地址空间,而不必依靠分段来实现内存保护。

Kernels thus simply set their segments to cover the entire address space and do not rely on segmentation to achieve memory protection.

它们使用的是页表的属性。进程的内存映射中存在的每个页面都有一个页面表条目,用于控制对其的访问。可以在此处,但最重要的是,有两个位控制允许哪种类型的访问:

What they do use is the page table's attributes. Every page that exists in a process's memory map has a page table entry governing access to it. An overview of their format can be seen here, but most crucially there are two bits that control what type of access is permitted:


  • 位1(R / W):0表示只读,1表示读写。

  • 位63(XD):0表示可执行文件,1表示不可执行。

不可能用这些标志表示可执行文件-未读-未写组合。如果页面在内存映射中根本不存在,那么它必须是可读的。

It is not possible to indicate an executable-noread-nowrite combination with these flags. If the page is at all present in the memory map, it must be readable.

英特尔最新的微体系结构Skylake中正在迅速推出一种解决方案,允许仅执行的内存:它是受洗的MPK功能(内存保护密钥),对此功能的支持在于Linux内核4.6刚刚发布。这些键占据页表项的四位62:59,并且可以用指示执行-未读-不写访问的键来标记内存区域。

A solution is fast approaching in Intel's latest microarchitecture, Skylake, which will allow execute-only memory: It is the feature baptized MPK (memory protection keys), support for which landed in Linux kernel 4.6 just recently released. The keys occupy the four bits 62:59 of the page table entry, and areas of memory can be tagged with a key indicating execute-noread-nowrite access.

这篇关于代码(.text)是否仅执行? .rodata是否可执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆