根据MSDN,PE的.rdata部分应包含调试目录和描述字符串。我在其他地方读过它包含只读程序数据。转储几个文件后,我发现.rdata包含IAT,负载配置表和安全异常处理程序表。有人可以澄清.rdata的用途吗,为什么我在其中发现的内容与两个描述都不相同?另外,导入信息不应该在.idata中吗?

我假设不同的编译器和同一编译器的不同版本对相同的部分进行不同的处理。如果是这样,我在哪里可以获得更多信息?

#1 楼

通常将各种只读数据集中到.rdata中。但是,这只是权宜之计,而不是必要。只要在数据目录中正确引用了数据,编译器和链接器就可以将任何数据放在任意位置。

第一个调用点应该是Microsoft的PE COFF规范(当前为v8.3)。关于理论与实践之间分歧的说明和指示可以在RE上的另一个主题中找到。只需使用数据目录中的信息即可。

#2 楼

好了,基本上来说,拥有尽可能少的部分是很方便的,因为每个部分都必须在新的物理页面上开始,因此您可能会在这里和那里浪费几KiB的物理内存。另外,它占用更多的内核内存,并需要更多的子节对象,而要设置的子节更多,则意味着要执行的代码更多,因此加载时间将稍长一些。导入表必须位于只读段中,但不必位于其自身的段中,因为可以使用PE头中的指针对其进行访问。它必须是只读的,因为否则用户代码可以修改IAT并劫持代码中或插入的dll中的小工具的调用。对于加载程序,它需要修改IAT本身。这意味着它暂时需要将PTE从只读更改为COW,对其进行写入,这会导致分配新的物理页,并且一旦完成,则再次读取以保护PTE。