我试图更好地理解PE格式,并且想知道PE文件中的节与数据目录之间的关系是什么。打开PE文件时,我注意到它们经常重叠,但是我不清楚它们为什么或如何关联,而且Microsoft的官方PE文件格式规范似乎并没有使它变得更清晰。
我知道节头的名称值可以更改,因此不能保证对特定块的引用,因此应依赖这些数据目录在文件中查找特定块。
在我打开的一个示例PE文件中,我注意到.text节具有与Import Address Table数据目录头相同的偏移量,尽管IAT大小被列为8,而.text节的大小是6804。相比之下,资源数据目录头声明其起始于16384,长度为1568-精确地与.rsrc节的条目相符。后者对我有意义,而前者则没有。
那么,节与数据目录的不同目的是什么?为什么这两个概念都存在,又为什么有时它们重叠,而这对他们而言似乎没有意义呢?
部分的目的是将事物包装为“几乎”具有相同的内存保护。
例如,让我们使用calc.exe:
此处的代码段的段保护(IMAGE_SECTION_HEADER.Characteritics
)设置为0x60000020:
IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
.idata节(导入节)的值为0x40000040:
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
在某些情况下,链接器可能会决定将相同的内存保护应用于不同的部分并将它们合并在一起(您可以使用/MERGE
链接器选项来强制执行此设置)。
引用马特·彼得雷克(Matt Pietrek)的精彩两部分文章“深入了解Win32便携式可执行文件格式”(可在此处(1/2) (2/2),此处(1/2) (2 / 2)和.chm格式(1/2) (2/2)):
如果两个部分具有相似的兼容属性,通常可以在链接时将它们合并为一个部分
如果这些部分共享相同的IMAGE_SCN_MEM_READ
/IMAGE_SCN_MEM_WRITE
保护,通常就是这样:这就是为什么在某些情况下您可能会将导入表放入代码部分的原因(即使强硬的导入表显然也不打算执行)。由于您只能阅读代码并导入部分(无法写入它们),因此链接器将它们合并到同一部分中就足够了。
在同一篇文章中:
例如,可以将.rdata合并到.text中,但是您不应该将.rsrc,.reloc或.pdata合并到其他部分中。在Visual Studio .NET之前,您可以将.idata合并到其他部分中。在Visual Studio .NET中,这是不允许的,但是在进行发行版本构建时,链接器通常会将.idata的某些部分合并到其他部分中,例如.rdata。
AFAIK,资源(.rsrc)和重定位(.reloc)节始终保持单独状态。之所以将资源部分保留下来,可能是因为某些API依赖它。
另一方面,数据目录会告诉您在哪里可以找到PE文件的重要部分(导入,导出,调试,TLS,资源,重定位等),即使合并了不同的部分,您仍然可以找到其中的相关部分。数据。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句