标记为“执行”和“读取”的可执行部分?

时间:2009-04-26 20:31:54

标签: winapi memory executable portable-executable

我注意到(至少在Win32上)在可执行文件中,代码段(.text)具有“读取”访问位设置,以及“执行”访问位。代码是阅读本身而不是执行本身是否有任何真正合理的理由?我认为这是其他部分的用途(例如.rdata)。

(具体来说,我说的是IMAGE_SCN_MEM_READ。)

3 个答案:

答案 0 :(得分:5)

IMAGE_SCN_MEM_EXECUTE |IMAGE_SCN_MEM_READ作为PAGE_EXECUTE_READ映射到内存中,相当于PAGE_EXECUTE_WRITECOPY。这是启用写时复制访问所必需的。写入时复制意味着任何修改页面的尝试都会导致正在创建的页面的新的进程私有副本。

需要写入副本有几个不同的原因:

  • 需要由加载程序重定位的代码必须具有此设置,以便加载程序可以执行修复。这很常见。
  • 在单个部分中包含代码和数据的部分也需要这样,以启用修改进程全局变量。代码&单个部分中的数据可以节省空间,并且可以通过使代码和代码使用的全局变量在同一页面上来改善局部性。
  • 尝试修改自身的代码。我相信这是相当罕见的。

答案 1 :(得分:1)

编译时常量,特别是长long或double值,通常会加载来自代码段的mov寄存器 address 语句。

答案 2 :(得分:0)

我能想到的一个例子是为了阅读代码的原因是允许自我修改代码。代码必须能够自行读取才能进行自我修改。

同时考虑相反的一面。禁止代码阅读本身会带来什么好处?我在这一方面有点挣扎,但我看不出这样做有什么好处。