Winapi 标记为“可执行”的可执行部分;执行;及;读“什么?”;?

Winapi 标记为“可执行”的可执行部分;执行;及;读“什么?”;?,winapi,memory,executable,portable-executable,Winapi,Memory,Executable,Portable Executable,我注意到(至少在Win32上)在可执行文件中,代码段(.text)设置了“读取”访问位和“执行”访问位。有没有真正合法的理由让代码阅读而不是执行本身?我认为这就是其他部分的用途(例如.rdata) (具体来说,我指的是。)IMAGE\u SCN\u MEM\u EXECUTE;IMAGE\u SCN\u MEM\u READ作为PAGE\u EXECUTE\u READ映射到内存中,这相当于PAGE\u EXECUTE\u WRITECOPY。这是启用写时复制访问所必需的。写时复制意味着任何修改

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


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

IMAGE\u SCN\u MEM\u EXECUTE;IMAGE\u SCN\u MEM\u READ
作为
PAGE\u EXECUTE\u READ
映射到内存中,这相当于PAGE\u EXECUTE\u WRITECOPY。这是启用写时复制访问所必需的。写时复制意味着任何修改页面的尝试都会导致创建页面的新进程专用副本

需要写拷贝的原因有几个:

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

我能想到的一个阅读代码的理由是允许自我修改代码。为了能够自我修改,代码必须能够读取自身


也考虑相反的一面。禁止代码读取本身有什么好处?我在这个问题上挣扎了一段时间,但我看不出这样做有什么好处

编译时常量,特别是对于long-long或double值,通常使用mov寄存器、来自代码段的地址语句加载