What is the relationship between sections and data directories in a PE file?
我试图更好地理解PE格式,并且想知道PE文件中节与数据目录之间的关系是什么。打开PE文件时,我注意到它们经常重叠,但是我不清楚它们为什么或如何关联,而且Microsoft的官方PE文件格式规范似乎并没有使它变得更加清晰。
我了解到节头的名称值可以更改,因此不能保证对特定块的引用,因此应依赖这些数据目录在文件中查找特定块。 >
在我打开的一个示例PE文件中,我注意到.text节具有与Import Address Table数据目录头相同的偏移量,尽管IAT大小被列为8,而.text节的大小是6804。相反,资源数据目录标头指出它始于16384,长度为1568,与.rsrc节的条目精确吻合。后者对我来说很有意义,而前者则没有。
那么节与数据目录的不同目的是什么?为什么这两个概念都存在,为什么它们有时会重叠在一起而对它们似乎没有意义呢?
部分用于打包具有几乎相同的内存保护的东西。
例如,以calc.exe为例:
此处的代码段的段保护(
1 | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
.idata节(导入节)的值为0x40000040:
1 | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
在某些情况下,链接器可能会决定将相同的内存保护应用于不同的部分并将它们合并在一起(您可以使用
引用Matt Matt Tretrek的精彩文章分为两部分:"深入了解Win32便携式可执行文件格式"(可在此处(1/2)(2/2),此处(1/2)找到) (2/2)和.chm格式(1/2)(2/2)):
If two sections have similar, compatible attributes, they can usually
be combined into a single section at link time
如果这些部分共享相同的
来自同一篇文章:
For example, it's OK to merge .rdata into .text, but you shouldn't
merge .rsrc, .reloc, or .pdata into other sections. Prior to Visual
Studio .NET, you could merge .idata into other sections. In Visual
Studio .NET, this is not allowed, but the linker often merges parts of
the .idata into other sections, such as .rdata, when doing a release
build.
AFAIK,资源(.rsrc)和重定位(.reloc)节始终保持单独状态。之所以单独保留资源部分,可能是因为某些API依赖它。
另一方面,数据目录告诉您在哪里可以找到PE文件的重要部分(导入,导出,调试,TLS,资源,重定位等),即使合并了不同的部分,您仍然可以找到相关数据。